在C ++ 11中替换元组中的类型

时间:2016-07-29 15:16:40

标签: c++ templates c++11 tuples stdtuple

我正在尝试在C ++中使用模板来执行以下操作:

我有这样的功能:

template<typename... Args>
void f1(const std::tuple<Args...>& t1);

在这个函数中,我想创建另一个元组t2,使得t1的每个元素都被复制到t2中的相同位置,除了类型A的元素,t2应该创建一个类型为B的对象。

但是,B的构造函数引用类型为A 的对象以及类型为C&的第二个参数。在转换之前创建C的实例,并且只要遇到B类型的对象,就应该将其作为第二个参数传递给A的构造函数。

这样的事情,只是完全概括:

std::tuple<int, B, double, B> Convert(std::tuple<int, A, double, A> tpl, C& c)
{
  return std::tuple<int, B, double, B>(
    std::get<0>(tpl),
    B(std::get<1>(tpl), c),
    std::get<2>(tpl),
    B(std::get<3>(tpl), c),
  );
}

2 个答案:

答案 0 :(得分:3)

注意:新问题要求更复杂的事情。给那些可能受益的人留下这个答案。

模板条件和模板包扩展的强大功能:

template<typename... Args>
void f1(const std::tuple<Args...>& t1) {
    std::tuple<typename std::conditional<
        std::is_same<A, Args>::value, B, Args>::type...> t2(t1);
    // Both Args are expanded in parallel, resulting in the same types
    // Do things with t2
}

答案 1 :(得分:1)

我想这可以解决问题:

#include<functional>
#include<tuple>
#include<cassert>

struct A {};
struct C {};
struct B { B(const A &, C &) {} };

template<typename T>
T g(const T &t, C &) { return t; }

B g(const A &a, C &c) {
    return B{a, c};
}

template<std::size_t... I, typename... Args>
void f(const std::tuple<Args...> &tup,std::index_sequence<I...>) {
    C c;
    auto val = std::make_tuple(g(std::get<I>(tup), c)...);
    assert((std::is_same<std::tuple<C, B, C>, decltype(val)>::value));
}

template<typename... Args>
void f(const std::tuple<Args...> &tup) {
    f(tup, std::make_index_sequence<sizeof...(Args)>());
}

int main() {
    auto tup = std::make_tuple(C{}, A{}, C{});
    f(tup);
}

请注意,此解决方案需要C ++ 14,主要是因为std::make_index_sequencestd::index_sequence 如果需要,您可以在线找到合适的C ++ 11实现。