1

所以我试图获得一个唯一的类型列表,并且我想摆脱我传递的列表可能包含的所有 const 重复项。我认为下面的代码应该可以工作,但 my_set 包含两次“int”。我究竟做错了什么?

#include <boost/mpl/vector.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/assert.hpp>

typedef boost::mpl::vector<float,int,float,const int>::type my_v;

typedef boost::mpl::transform
    < my_v
    , boost::remove_cv<boost::mpl::_1>::type
    >::type my_v2;

typedef boost::mpl::fold
    < my_v2
    , boost::mpl::set0<>
    , boost::mpl::insert
        < boost::mpl::_1
        , boost::mpl::_2
        >
>::type my_set;

BOOST_MPL_ASSERT_RELATION( boost::mpl::size<my_set>::value, ==, 2 ); // Fails
4

1 回答 1

2

是的,正如 cv_and_he 所说,这是因为 boost::remove_cv::type。

将 ::type 添加到 boost::remove_cv 将强制对表达式进行评估,并使 remove_cv 评估 _1 表达式本身,而不是基础参数。这里的 transform 是一个递归函数,所以我们应该删除 '::type' 以允许在整个转换表达式展开后对参数进行惰性求值。

看下面的测试结果,

#include <boost/mpl/vector.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/assert.hpp>
#include <iostream>
#include <typeinfo>
#include <cxxabi.h>

typedef boost::mpl::vector<float,int,float,const int>::type my_v;

typedef boost::mpl::transform<my_v,
                              boost::remove_cv<boost::mpl::_1>::type
                              >::type my_v2;

typedef boost::mpl::fold< my_v2,
                          boost::mpl::set0<>,
                          boost::mpl::insert<boost::mpl::_1,
                                             boost::mpl::_2
                                             >
                          >::type my_set;

// BOOST_MPL_ASSERT_RELATION( boost::mpl::size<my_set>::value, ==, 2 ); // Fails

int main()
{
  int status;
  std::cout << abi::__cxa_demangle(typeid(boost::remove_cv<boost::mpl::_1>::type).name(), 0, 0, &status)
            << '\n'
            << abi::__cxa_demangle(typeid(boost::remove_cv<boost::mpl::_1>).name(), 0, 0, &status)
            << '\n'
            << abi::__cxa_demangle(typeid(my_v2).name(), 0, 0, &status)
            << std::endl;
}

输出,

mpl_::arg<1>
boost::remove_cv<mpl_::arg<1> >
boost::mpl::v_item<int const, boost::mpl::v_item<float, boost::mpl::v_item<int, boost::mpl::v_item<float, boost::mpl::vector0<mpl_::na>, 0>, 0>, 0>, 0>
于 2013-11-15T13:31:43.220 回答