巧妙的检测占位符
boost提供了从_1到_9的占位符。具体定义如下:
boost::arg<1> _1; boost::arg<2> _2; boost::arg<3> _3; boost::arg<4> _4; boost::arg<5> _5; boost::arg<6> _6; boost::arg<7> _7; boost::arg<8> _8; boost::arg<9> _9; template< int I > struct arg { arg() { } template< class T > arg( T const & /* t */ ) { // static assert I == is_placeholder<T>::value typedef char T_must_be_placeholder[ I == is_placeholder<T>::value? 1: -1 ]; } }; template< int I > bool operator==( arg<I> const &, arg<I> const & ) { return true; } template< int I > struct is_placeholder< arg<I> > { enum _vt { value = I }; }; template< int I > struct is_placeholder< arg<I> (*) () > { enum _vt { value = I }; }; template< class T > struct is_placeholder { enum _vt { value = 0 }; };说明:
1.is_placeholder模板函数主要用来设置value值,如果模板参数T不是arg<I>类型,则设置为0.下面的代码是z变量的值就是9.而q变量的值就是0,因为string不是arg<I>类型。
2.利用数组的初始化长度不能小于0,来做编译期检测。比如:如果表达式计算结果为-1,也就是char a[-1],则编译器会报错。上面代码的typedef就采用了这种机制。这也说明==,?:操作符都是可以在编译期间求值的。
int z = boost::is_placeholder<boost::arg<9> >::value; int q = boost::is_placeholder<string >::value; boost::arg<1> arg1(_1);//编译通过,因为_1是占位符 string str; boost::arg<1> arg2(str);//编译不通过,因为str不是占位符 /usr/src/boost_1_47_0/boost/bind/arg.hpp: In constructor ‘boost::arg<I>::arg(const T&) [with T = std::basic_string<char>, int I = 1]’: In file included from /usr/src/boost_1_47_0/boost/bind/bind.hpp:29:0, from /usr/src/boost_1_47_0/boost/bind.hpp:22, from main.cpp:12: main.cpp:59:27: instantiated from here /usr/src/boost_1_47_0/boost/bind/arg.hpp:37:22: error: size of array is negative