我正在尝试在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),
);
}
答案 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_sequence
和std::index_sequence
如果需要,您可以在线找到合适的C ++ 11实现。