使用boost :: mpl :: bool_而不是const bool的优点

时间:2010-10-21 11:42:51

标签: c++ templates metaprogramming

我对使用

的优点感到困惑
bool_<true> 

bool_<false> 

在模板元编程的上下文中简单地使用const bools的类型。

boost :: mpl库显然更喜欢第一种方法,并定义辅助函数,如and_,or_来帮助管理这样的bool_。条件元函数,如if_“取”bool_作为第一个(模板)参数,但在幕后“调用”if_c元函数,它期望(const)bool作为第一个(模板)参数。

这个决定背后有什么争论?

提前感谢您的帮助!

3 个答案:

答案 0 :(得分:11)

这是一个简短的例子,我不时地使用这些类型。使用const bool:

这个例子是不可能的
void do_something(boost::mpl::bool_<true>)
{
   ...
}

void do_something(boost::mpl::bool_<false>)
{
   ...
}

根据参数的类型调用这两个函数之一:

template<class T>
void doIt(void)
{
   do_something(boost::mpl::bool_<boost::is_pointer<T>::val>())
}

在这种情况下,将调用第一个或第二个函数,具体取决于类型T是否为指针的事实。这些类型允许您使用函数重载,使用const bool是不可能的。使用const bool,您必须在运行时决定采用哪个分支。如果被调用的函数本身是模板,如果它们被实例化为非预期的类型,则这是特别重要的。上面的第一个函数定义可能包含只编译指针的代码。

答案 1 :(得分:8)

所有这些都是为了创建足够的一致性,库可以提供有用的功能。 MPL协议是:“所有元函数参数(和返回)都是类型。”这允许我们编写可以在元函数上一般操作的模板。例如,此模板接受任何元函数(或在C ++ 03中具有最多N个参数的任何元函数):

template <template <class...> class some_metafunction>
struct wrapper;

一旦允许某些模板参数为非类型,就不可能编写这样的包装器。对于我们关心的实际例子,这种一致性允许库分离和评估MPL lambda表达式。如果允许元函数参数是非类型,那么该特性将无法实现,因为没有办法写出从其参数xxx a所需的所有部分特化> {在xxx<a1,a2,a3,...>

一个不那么有趣,即使不是那么有效的部分原因是,许多事情变得不像我们在MPL中那样冗长。比较:

and_<mf0<x,y>, mf1<z>, mf2<x,z> >::value

VS

mf0<x,y>::value && mf1<z>::value && mf2<x,z>::value

答案 2 :(得分:2)

我想有一个原因是bool_<...>是类型,当使用它们作为元函数的结果时,你将永远不必停下来思考你的结果是否是一个类型而你必须做

typedef some_type result;

或一个值,必须以

的形式返回
const static ??? result = some_value;

您还必须跟踪类型。

另外,我怀疑(我还没有使用过Boost.MPL)他们都有一个result类型的嵌套引用自己,所以你可以通过派生它们来编写元函数:

template< bool b >
struct my_meta_func : bool_<b> {};

并可以调用my_meta_func::result