如何为可变模板子项生成元组?
How to generate tuple for variadic templates children?
简而言之:如何从给定类型的子项创建可变元组?
在下面的代码中,get_children 调用中存在错误的子类型。目标是接收具有从给定元素派生的 Child 的元组。
template<typename T>
class Elem{
public:
T e;
class Child{ public: T c; };
Child child() { return Child{ .c = e}; };
};
template <typename... T>
class Collection{
public:
using arr = std::tuple<T...>;
arr elems;
using children = std::tuple<T...::Child>; /// **** HERE IS ERROR ***
auto get_children(){
children res;
get_child<sizeof...(T)-1>( res );
return res;
}
private:
template< size_t Num >
auto get_child( children &res ){
std::get<Num>(res) = std::get<Num>(elems).child();
get_child<Num-1>(res);
}
template<>
auto get_child<0>( children &res ){
std::get<0>(res) = std::get<0>(elems).child();
}
};
提前致谢!
因为你标记了 c++17,所以使用 apply
:
#include <iostream>
#include <tuple>
#include <boost/type_index.hpp>
template<typename T>
class Elem{
public:
T e;
class Child{ public: T c; };
Child child() { return Child{ .c = e}; };
};
template <typename... T>
class Collection{
public:
using arr = std::tuple<T...>;
arr elems;
auto get_children(){
return std::apply( [](auto&&... e){ return std::make_tuple( e.child()... ); } , elems);
}
private:
};
int main()
{
Collection<Elem<int>,Elem<char>,Elem<float>> c;
auto t = c.get_children();
std::cout << boost::typeindex::type_id_with_cvr<decltype(t)>().pretty_name() << std::endl;
// std::tuple<Elem<int>::Child, Elem<char>::Child, Elem<float>::Child>
}
怎么样
using children = std::tuple<typename T::Child...>;
?
我的意思是...单一类型是 T::Child
因此,要重复类型,您必须在类型后面放置省略号 (...
),因此 T::Child...
。
但是,给定泛型类型 T
,T::Child
可以是类型,也可以是成员或方法。所以你需要在typename
之前通知编译器后面的T::Child
是一个类型而不是成员或其他。
简而言之:如何从给定类型的子项创建可变元组?
在下面的代码中,get_children 调用中存在错误的子类型。目标是接收具有从给定元素派生的 Child 的元组。
template<typename T>
class Elem{
public:
T e;
class Child{ public: T c; };
Child child() { return Child{ .c = e}; };
};
template <typename... T>
class Collection{
public:
using arr = std::tuple<T...>;
arr elems;
using children = std::tuple<T...::Child>; /// **** HERE IS ERROR ***
auto get_children(){
children res;
get_child<sizeof...(T)-1>( res );
return res;
}
private:
template< size_t Num >
auto get_child( children &res ){
std::get<Num>(res) = std::get<Num>(elems).child();
get_child<Num-1>(res);
}
template<>
auto get_child<0>( children &res ){
std::get<0>(res) = std::get<0>(elems).child();
}
};
提前致谢!
因为你标记了 c++17,所以使用 apply
:
#include <iostream>
#include <tuple>
#include <boost/type_index.hpp>
template<typename T>
class Elem{
public:
T e;
class Child{ public: T c; };
Child child() { return Child{ .c = e}; };
};
template <typename... T>
class Collection{
public:
using arr = std::tuple<T...>;
arr elems;
auto get_children(){
return std::apply( [](auto&&... e){ return std::make_tuple( e.child()... ); } , elems);
}
private:
};
int main()
{
Collection<Elem<int>,Elem<char>,Elem<float>> c;
auto t = c.get_children();
std::cout << boost::typeindex::type_id_with_cvr<decltype(t)>().pretty_name() << std::endl;
// std::tuple<Elem<int>::Child, Elem<char>::Child, Elem<float>::Child>
}
怎么样
using children = std::tuple<typename T::Child...>;
?
我的意思是...单一类型是 T::Child
因此,要重复类型,您必须在类型后面放置省略号 (...
),因此 T::Child...
。
但是,给定泛型类型 T
,T::Child
可以是类型,也可以是成员或方法。所以你需要在typename
之前通知编译器后面的T::Child
是一个类型而不是成员或其他。