我正在尝试阅读boost标头,以弄清楚他们是如何设法实现
的or_<...>
和
and_<...>
元功能因此:
1)他们可以拥有任意数量的参数(好吧,最多可以说5个参数)
2)它们具有短路行为,例如:
or_<false_,true_,...>
不会实例化true_之后的任何内容(因此它也可以声明但未定义)
不幸的是,预处理器元编程让我无法完成任务:P
提前感谢您提供任何帮助/建议。
答案 0 :(得分:2)
以下是短路可以用于三参数版本的方法
template<typename T1, typename T2, typename T2>
struct or_ : conditional<T1::value, true_, or<T2, T3>>::type
{ };
也就是说,如果T1::value
为真,则会继承true_
,否则会继承or<T2, T3>
。你需要一个停止标准,就像@begemoth显示的那样:第一个类型为or_
的专业none_t
,它将::value
定义为false
。
答案 1 :(得分:1)
我不熟练使用Boost.MPL,所以我只能猜测它是如何实现的,但我知道如何做到这一点。
让我们从你的第一个问题开始吧。这有两个解决方案,一个用于C ++ 98(有限数量的参数),另一个用于C ++ 0x。
我们像这样定义or_
:
struct null_type { };
template<typename T1 = null_type, typename T2 = null_type, typename T3 = null_type>
struct or_
{
static const bool value = T1::value || T2::value || T3::value;
};
template<typename T1, typename T2>
struct or_<T1, T2, null_type>
{
static const bool value = T1::value || T2::value;
};
template<typename T1>
struct or_<T1, null_type, null_type>
{
static const bool value = T1::value;
};
template<>
struct or_<null_type, null_type, null_type>
{
static const bool value = false;
};
struct true_ { static const bool value = true; };
struct false_ { static const bool value = false; };
要获取元函数的更多参数,您需要为or_
模板指定更多参数。您可以使用Boost.Preprocessor生成特化。
在C ++ 0x中,您可以使用可变参数模板:
template<typename... T>
struct or_;
template<>
struct or_<>
{
static const bool value = false;
};
template<typename T1, typename... Ts>
struct or_<T1, Ts...>
{
static const bool value = T1::value || or_<Ts...>::value;
};
这个经典的递归列表处理代码。要熟悉这种风格,请阅读函数式编程。
第二个问题更简单。 or_
和and_
元函数参数是类型,即nullary元函数,只有在需要它们的值时才调用它们(这是C ++中逻辑运算符的语义)。使用简单的函数,类似的代码是:
bool true_() { return true; }
bool false_() { return false; }
bool or_(bool (*x)(), bool (*y)())
{
return x() || y();
}