transform 期望的第二个参数是一个你没有传递的一元操作。
在您的情况下,my_type 不是 mpl 所期望的 metafunction,因为它正在使用可变参数列表。
在最简单的情况下,metafunction 公开了 type 类型定义或 ststic bool value。例如:
template <typename T>
struct add_pointer {
using type = T*;
};
注意add_pointer 如何转换提供的模板参数。这是unary 操作的示例,因为它只需要一个模板参数T。
在您的示例中,my_type 纯粹是一种类型,不能用作元函数或操作,因为它不符合 transform 元函数所要求的 metafunction 标准,该元函数具有 type 字段表示转换后的类型。
在某些情况下,简单的模板类型会转换为metafunction,如下面的Detailed Reasoning 部分所述。
文档参考:http://www.boost.org/doc/libs/1_31_0/libs/mpl/doc/ref/Reference/transform.html
代码:
#include <boost/mpl/vector.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/equal.hpp>
#include <type_traits>
#include <typeindex>
#include <iostream>
template <class... T>
struct my_type{};
using namespace boost::mpl;
using test_type = vector<int, double>;
template <typename T>
struct add_my_type {
using type = my_type<T>;
};
using result_type = typename transform< test_type, add_my_type<_1> >::type;
int main() {
static_assert (equal<result_type, vector< my_type<int>, my_type<double> >>::value, "Nope!!");
std::cout << typeid(result_type).name() << std::endl;
}
LIVE DEMO
详细原因
上面解释的原因很简短,应该足以回答这个问题。但是,让我们尽可能深入研究细节。
免责声明:我不是 boost::mpl 方面的专家。
根据 OP 下面的评论,如果我们将 my_type 更改为:
template <class T>
struct my_type{};
但这与我之前提到的并不顺利,即operation 需要一个type 标识符。那么,让我们看看 mpl 在幕后做了什么:
struct transform 有点像:
template<
typename Seq1 = mpl::na
, typename Seq2OrOperation = mpl::na
, typename OperationOrInserter = mpl::na
, typename Inserter = mpl::na
>
struct transform {
boost::mpl::eval_if<
boost::mpl::or_<
boost::mpl::is_na<OperationOrInserter>,
boost::mpl::is_lambda_expression<my_type<mpl_::arg<1> > >,
boost::mpl::not_<boost::mpl::is_sequence<my_type<mpl_::arg<1> > > >,
mpl_::bool_<false>,
mpl_::bool_<false>
>,
boost::mpl::transform1<
boost::mpl::vector<int, double>,
my_type<mpl_::arg<1>>,
mpl_::na
>,
boost::mpl::transform2<boost::mpl::vector<int, double>,
my_type<mpl_::arg<1> >,
mpl_::na, mpl_::na>
>
};
看这里的重要部分是is_lambda_expression 元函数,它基本上检查您的Operation 是否满足metafunction 的要求。
在应用了一些繁重的宏和模板机制和特化之后,上面的检查合成了下面的结构:
template<
typename IsLE, typename Tag
, template< typename P1 > class F
, typename L1
>
struct le_result1
{
typedef F<
typename L1::type
> result_;
typedef result_ type;
};
这里,F 是您的 my_type,L1 是 placeholder。所以,本质上,上面的结构只不过是add_my_type,我在最初的回复中已经展示了它。
如果到目前为止我是正确的,le_result1 是 operation,它将在您的 sequence 上执行。