巧妙的检测占位符
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