c – 使用boost :: mpl占位符评估的不一致行为

前端之家收集整理的这篇文章主要介绍了c – 使用boost :: mpl占位符评估的不一致行为前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在以下代码中(为演示而简化):
namespace mpl = boost::mpl;

  using if1 = mpl::if_<std::is_same<double,mpl::_1>,double,void>;
//using if2 = mpl::if_<std::is_same<double,typename std::common_type<double,mpl::_1>::type,void>;

  using apply1 = boost::mpl::apply<if1,double>::type;
//using apply2 = boost::mpl::apply<if2,double>::type;

在std :: is_same< double,mpl :: _ 1>中,占位符被正确地替换为double,就好像实例化是显式的std :: is_same< double,double>这导致正确/预期的行为.

但是,在std :: common_type< double,占位符未被替换,就好像实例化是显式std :: common_type< double,mpl _ :: arg< 1>>,这会导致以下错误因为显然没有“共同”类型:

error: incompatible operand types ('double' and 'mpl_::arg<1>')

问题:为什么mpl :: _ 1占位符在std :: is_same中正确转换/替换为double,而不是在std :: common_type中?有解决方法吗?

解决方法

在应用lambda之前,您通过访问嵌套的:: std :: common_type类型来强制实施过于急切的实例化.将typename std :: common_type< double,mpl :: _ 1> :: type替换为std :: common_type< double,mpl :: _ 1>你应该都很好.

编辑:道歉的坏建议.我没看到你在做什么.麻烦的是mpl :: apply会通过首先通过mpl :: lambda运行它来将占位符表达式转换为lambda表达式.这将导致std :: common_type< double,mpl :: _ 1>包含在mpl :: protect中,它将阻止它在第一次传递中被计算,而mpl :: if_将不会在第二次传递中对其进行求值,因为它将其第二个和第三个参数视为普通类型,而不是占位符表达式.您可以使用mpl :: bind强制在mpl :: if_之前评估std :: common_type.这样,mpl :: if_看到if_< some-condition,void>,而且一切都是正确的.

#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/bind.hpp>
#include <boost/mpl/quote.hpp>

namespace mpl = boost::mpl;

template<typename T,typename U> using common_type2 = std::common_type<T,U>;
using if2 = mpl::if_<
                std::is_same<double,mpl::bind<mpl::quote2<common_type2>,void>;
using apply2 = boost::mpl::apply<if2,double>::type;
static_assert(std::is_same<apply2,double>::value,"works");

HTH!

猜你在找的C&C++相关文章