前两天发现了VC2010 tr1库中bind实现的一个bug,当时只是作了记录,没有详细分析.但作为一个QA,不找出问题所在实在不算称职,于是就有了这篇捉虫记.
闲言少叙,书归正传,tr1库就不多作介绍了,有兴趣的同学可以去 wikipedia上看.bind,顾名思义,就是把参数与函数绑定,以利于我们进行函数式编程,是从boost的bind库引入的,对bind不是很了解的可以看陈硕同学的这篇
以boost::function和boost:bind取代虚函数
假定笔者是 vc2010的QA,在做bind的功能测试,开始用gtest写test case, (笔者一般用gtest作为C++测试框架,就写到文章中了,但ms肯定不会用啦.笔者不在ms,请勿对号入座)
先写几个简单的函数供测试之用.
int Add(int left, int right)
{
return left + right;
}
int Sub(int left, int right)
{
return left - right;
}
int Mul(int left, int right)
{
return left * right;
}
{
return left + right;
}
int Sub(int left, int right)
{
return left - right;
}
int Mul(int left, int right)
{
return left * right;
}
再写测试用例.先是几个简单的
1 把值绑定到函数指针
TEST(Bind, FundPtr_Values)
{
auto f0 = std::tr1::bind(Sub, 5, 3);
ASSERT_EQ(2, f0());
}
{
auto f0 = std::tr1::bind(Sub, 5, 3);
ASSERT_EQ(2, f0());
}
2 把值绑定到仿函数
TEST(Bind, Functor_Values)
{
auto f0 = std::tr1::bind(std::minus<int>(), 6, 4);
ASSERT_EQ(2, f0());
}
{
auto f0 = std::tr1::bind(std::minus<int>(), 6, 4);
ASSERT_EQ(2, f0());
}
3 把占位符绑定到函数指针
TEST(Bind, FuncPtr_Placeholder)
{
auto f0 = std::tr1::bind(Sub, std::tr1::placeholders::_1, 8);
ASSERT_EQ(12, f0(20));
}
{
auto f0 = std::tr1::bind(Sub, std::tr1::placeholders::_1, 8);
ASSERT_EQ(12, f0(20));
}
4 将占位符绑定到仿函数
TEST(Bind, Functor_Placeholder)
{
auto f0 = std::tr1::bind(std::minus<int>(), std::tr1::placeholders::_2, std::placeholders::_1);
ASSERT_EQ(12, f0(8, 20));
}
{
auto f0 = std::tr1::bind(std::minus<int>(), std::tr1::placeholders::_2, std::placeholders::_1);
ASSERT_EQ(12, f0(8, 20));
}
运行测试
testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
int ret = RUN_ALL_TESTS();
一切OK.
来个复杂的,将bind返回结果再bind到函数,用于进行高阶函数演算.
TEST(Bind, SquareDiff_FuncPtr)
{
auto f0 = std::tr1::bind(Mul,
std::tr1::bind(Add, std::tr1::placeholders::_1, std::tr1::placeholders::_2),
std::tr1::bind(Sub, std::tr1::placeholders::_1, std::tr1::placeholders::_2));
ASSERT_EQ(16, f0(5, 3));
}
{
auto f0 = std::tr1::bind(Mul,
std::tr1::bind(Add, std::tr1::placeholders::_1, std::tr1::placeholders::_2),
std::tr1::bind(Sub, std::tr1::placeholders::_1, std::tr1::placeholders::_2));
ASSERT_EQ(16, f0(5, 3));
}