boost::mpl::or_ 和 boost::mpl::and_ 的不同行为
Different behavior of boost::mpl::or_ and boost::mpl::and_?
下面的代码试图测试boost::mpl::or_
和boost::mpl::and_
的短路行为:
#include <vector>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_scalar.hpp>
// Dummy is forward declared and never defined
template <class T> class dummy;
// If T is a scalar evaluates to T without trying to compute the result of
// boost::mpl::is_scalar< dummy<T>, otherwise it fails at compile time.
template <class T>
class testOr
: public boost::mpl::eval_if<
boost::mpl::or_< boost::is_scalar<T>, boost::is_scalar< dummy<T> > >,
boost::mpl::identity<T>,
dummy<T>
>
{};
// If T is not a scalar evaluates to T without trying to compute the result of
// boost::mpl::is_scalar< dummy<T>, otherwise it should fail at compile time.
template <class T>
class testAnd
: public boost::mpl::eval_if<
// It appears that is_scalar< dummy<T> > is not instantiated and the operation
// evaluates to false
boost::mpl::and_< boost::is_scalar<T>, boost::is_scalar< dummy<T> > >,
dummy<T>,
boost::mpl::identity<T>
>
{};
int main() {
static_assert(boost::is_same< testOr< double >::type, double>::type::value,"Fails at compile time");
// The following line causes failures at compile time due to incomplete type definition
//static_assert(boost::is_same< testOr< std::vector<double> >::type, double>::type::value,"Fails at compile time");
static_assert(boost::is_same< testAnd< std::vector<double> >::type, std::vector<double> >::type::value,"Fails at compile time");
// The following should cause failure at compile time due to incomplete type definition, but works instead!
static_assert(boost::is_same< testAnd< double >::type , double >::type::value,"Fails at compile time");
return 0;
}
虽然我希望这段代码由于类型定义不完整而在编译时失败,但它实际上有效:
>icpc --version
icpc (ICC) 12.1.3 20120212
Copyright (C) 1985-2012 Intel Corporation. All rights reserved.
>icpc -gcc-name=gcc-4.5 -std=c++0x -o ex-4.0.x ex-4.0.cc
所以,我想理解的一点是:
boost::mpl::or_
和boost::mpl::and_
评估其参数的方式是否存在不一致,或者最有可能的是,我无法捕获的代码中是否存在错误?
你为什么认为,or_
的第二个参数不会被评估? is_scalar
可以与未定义的类型一起使用。
例如,在这种情况下,您也会遇到错误。
// If T is not a scalar evaluates to T without trying to compute the result of
// boost::mpl::is_scalar< dummy<T>, otherwise it should fail at compile time.
template <class T>
class testAnd
: public boost::mpl::eval_if<
// It appears that is_scalar< dummy<T> > is not instantiated and the operation
// evaluates to false
boost::mpl::and_< boost::is_scalar<T>, boost::is_scalar< dummy<T> > >,
boost::mpl::identity<T>,
dummy<T>
>
{};
既然boost::is_scalar<T>
是真的,但在你的情况下boost::is_scalar<dummy<T>>
是假的,所以。
看,http://liveworkspace.org/code/a792e18ca16a0410a67a6eee8c550bd9
你的想法中有一个逻辑错误 - 如果第一个参数的计算结果为 true
,||
会短路。 is_scalar<std::vector<double>>
是false
,这意味着第二个参数需要被计算。相反,如果第一个参数是false
,&&
会短路,如上所述。
相关文章:
- 将 Boost MPL 容器替换为 C++17 功能
- boost::mpl 不使用(甚至不兼容)std::p air 的原因是什么?
- 使用boost :: mpl :: find_if带有自定义谓词
- 检查两个 Boost.MPL 序列是否按任何顺序包含相同的类型
- 是否可以使用 static_cast 从可变参数枚举创建 boost::mpl::list_c
- 使用转换后的“boost::mpl::vector”进行标记调度
- Boost Mpl Pop_back中的序列平等
- 如何将 boost::mpl::vector 转换为另一个 boost::mpl::vector
- 在 boost::mpl::for_each() 中调用通用 lambda
- Boost mpl::vector and hana
- Boost MPL-按顺序声明每种类型的类
- boost::mpl::字符串大小错误消息
- 如何在 Boost.MPL 中使用嵌套元函数
- 如何使用Boost MPL在一个函数中具有多个返回点
- boost::mpl::or_ 和 boost::mpl::and_ 的不同行为
- boost::mpl::if_编译错误
- Boost mpl列表和auto_test_case_template编译错误
- C++朋友在boost::mpl::vector中的每个类
- 运行时在boost::mpl::vector中查找第一个匹配项
- 为boost mpl列表中的每种类型继承容器