enable_if是用来(可以用来)控制重载函数的是否可用,这一点没有直观感受,比如,我写了一个形式的重载函数,但是我需要在某种条件下取消它,这时候它就可以派上用场,当然这里是模板函数.
function的构造函数有类似下面的形式:
template<typename Functor>
BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
#ifndef BOOST_NO_SFINAE
,typename enable_if_c<
(boost::type_traits::ice_not<
(is_integral<Functor>::value)>::value),
int>::type = 0
#endif // BOOST_NO_SFINAE
) :
function_base()
{
this->assign_to(f);
}
#ifndef BOOST_NO_SFINAE
BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
#else
BOOST_FUNCTION_FUNCTION(int zero) : function_base()
{
BOOST_ASSERT(zero == 0);
}
我还不知道如何分析和理解这些宏,这个BOOST_FUNCTION_FUNCTION会替换成你外面的名字function,这两个构造函数有些奇怪,比如:
function<int(int)> f=0;
对于第一个模板形式,虽然你知道那里的Functor表示仿函数,但是事实上编译器只能当成'某种类型',并且不会排除int,它会被选中嘛,当然啦,int也是一种typename.这是我们不想看到的,愚蠢地把0当成了函数对象初始化下面的内容.
这个时候,那句enable_if_c起作用了,它里面的意思是说,如果Functor不是内部类型,那第二个参数就是int型,且有默认参数0,否则,将产生参数推导错误,而这并不会引发编译错误,只是将这个推导错误的重载形式函数从候选集中去掉.
可以在boost/utility里找到enable_if.hpp,看到enable_if_c的定义很简单:
template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> {};
如果第一个参数是true,则内嵌型别type就是第二个参数,否则,没有type的定义.第二个参数会被选中的原因是,0可以转型成clear_type*.
评论