gpt4 book ai didi

c++ - 将 boost mpl lambda 与可变参数模板类一起使用

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:44:50 25 4
gpt4 key购买 nike

我很难理解为什么以下简单程序无法编译。我有一个可变参数模板类(下面的 my_type),我想用它来转换 mpl vector 。以下片段导致编译错误“/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp:38:19:‘template’关键字后的‘apply’不引用模板”。

#include <boost/mpl/vector.hpp>
#include <boost/mpl/transform.hpp>

template <class... T>
struct my_type{};

using namespace boost::mpl;

using test_type = vector<int, double>;

// expected result is vector< my_type<int>, my_type<double> >
using result_type = transform< test_type, my_type<_> >::type;

int main() {

}

my_type 采用单个模板参数效果很好,但我想了解为什么可变参数版本不起作用。提前致谢!

最佳答案

transform 期望的第二个参数是您没有传递的一元运算。

在您的情况下,my_type 不是 mpl 期望的 元函数,因为它使用可变参数列表。

元函数 在最简单的情况下公开了一个type typedef 或一个ststic bool value。例如:

template <typename T>
struct add_pointer {
using type = T*;
};

请注意 add_pointer 如何转换提供的模板参数。这是一个 unary 操作的例子,因为它只需要一个模板参数 T

在您的示例中,my_type 纯粹是一种类型,不能用作元函数或操作,因为它不满足 要求的 元函数 标准>transform 元函数,它有一个 type 字段来指示转换后的类型。

在某些情况下,一个简单的模板类型被转换成一个元函数,如下面的详细推理部分所述。

文档引用: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 是否满足 元函数 的要求。

在应用了一些繁重的宏和模板机制和特化之后,上面的检查合成在结构下面:

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_typeL1placeholder 。因此,从本质上讲,上述结构只不过是我在初始响应中显示的 add_my_type

如果到目前为止我是正确的,le_result1 是将对您的序列 执行的操作

关于c++ - 将 boost mpl lambda 与可变参数模板类一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41007176/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com