C++ 创建一个元组,该元组包含不同的驱动类元素,其构造函数接收到一个int类型,该类型由元组中的索引确定
我有一个基类,其构造函数接收一个名为id的int类型,还有几个不同的派生类,其构造函数的形式与基类相同 现在我想创建一个包含这些元素的元组,其构造函数接收一个由其在该元组中的索引确定的id。就像下面的哑函数所做的那样:C++ 创建一个元组,该元组包含不同的驱动类元素,其构造函数接收到一个int类型,该类型由元组中的索引确定,c++,templates,variadic-templates,template-meta-programming,stdtuple,C++,Templates,Variadic Templates,Template Meta Programming,Stdtuple,我有一个基类,其构造函数接收一个名为id的int类型,还有几个不同的派生类,其构造函数的形式与基类相同 现在我想创建一个包含这些元素的元组,其构造函数接收一个由其在该元组中的索引确定的id。就像下面的哑函数所做的那样: class Base(){ Base(int id){} } class Derive1, Derived2...Derivedn : public Base(){ Derive(int id):Base(id){} } auto make_derives_
class Base(){
Base(int id){}
}
class Derive1, Derived2...Derivedn : public Base(){
Derive(int id):Base(id){}
}
auto make_derives_tuple()->decltype(...){
//manually write each elements' index in the tuple seems too ugly and unnecessary
return std::make_tuple(Derive1(0),Derived2(1),Derived3(2)...);
}
如果派生类的数量为三:
struct Base{
Base(int id){
id_=id;
}
int id_;
};
struct Derive:public Base{
Derive(int id):Base(id){
}
};
struct Derive2:public Base{
Derive2(int id):Base(id){
}
};
auto make_derive_tuple()->decltype (std::make_tuple(Derive(0),Derive2(1),Derive3(2))){
//I want the int passed to the derived class's construor automatically generated according to it's position in the tuple
return std::make_tuple(Derive(0),Derive2(1),Derive3(2));
}
但是在元组中手动编写每个元素的索引以传递给构造函数似乎太难看了,也没有必要。有什么优雅的方法可以做到这一点吗?比如使用可变模板类或函数。我不认为简单地迭代类是一种优雅的方法,比如
Derived1
,Derived2
,Derived3
,等等
但如果您可以按如下方式或以类似方式对派生类进行模板化,并添加模板索引,则情况就不同了
template <std::size_t>
struct Derived : public Base
{ Derived (int id) : Base{id} {} };
下面是一个完整的编译示例
#include <tuple>
#include <utility>
#include <type_traits>
struct Base
{ Base (int) {} };
template <std::size_t>
struct Derived : public Base
{ Derived (int id) : Base{id} {} };
template <std::size_t ... Is>
auto make_helper (std::index_sequence<Is...> const &)
{ return std::make_tuple(Derived<Is+1u>{Is}...); }
template <std::size_t N>
auto make_derives_tuple ()
{ return make_helper(std::make_index_sequence<N>{}); }
int main()
{
auto t = make_derives_tuple<3u>();
using T0 = decltype(t);
using T1 = std::tuple<Derived<1u>, Derived<2u>, Derived<3u>>;
static_assert( std::is_same<T0, T1>::value, "!" );
}
下面是一个完整的编译示例(其中我重命名了派生类a
、B
、C
和D
)
#include <tuple>
#include <utility>
#include <type_traits>
struct Base
{ Base (int) {} };
struct A : public Base
{ A (int id) : Base{id} {} };
struct B : public Base
{ B (int id) : Base{id} {} };
struct C : public Base
{ C (int id) : Base{id} {} };
struct D : public Base
{ D (int id) : Base{id} {} };
template <typename ... Ts, std::size_t ... Is>
auto make_helper (std::index_sequence<Is...> const &)
{ return std::make_tuple(Ts{Is}...); }
template <typename ... Ts>
auto make_derives_tuple ()
{ return make_helper<Ts...>(std::index_sequence_for<Ts...>{}); }
int main()
{
auto t = make_derives_tuple<A, B, C, D>();
using T0 = decltype(t);
using T1 = std::tuple<A, B, C, D>;
static_assert( std::is_same<T0, T1>::value, "!" );
}
#包括
#包括
#包括
结构基
{Base(int){};
结构A:公共基础
{A(int-id):基{id}{};
结构B:公共基础
{B(int-id):基{id}{};
结构C:公共基础
{C(int-id):基{id}{};
结构D:公共基础
{D(int-id):基{id}{};
模板
自动生成辅助对象(std::index\u序列常量&)
{return std::make_tuple(Ts{Is}…;}
模板
自动生成\u派生\u元组()
{返回make_helper(std::index_sequence_for{});}
int main()
{
auto t=make_派生_tuple();
使用T0=decltype(t);
使用T1=std::tuple;
静态断言(std::is_same::value,“!”;
}
你可以提供实际的示例代码,即使它只包含两个派生类吗?上面的草图并不十分清楚,因为它不遵循C++语法。非常感谢!第二个真的很有用,我也从第一个例子中学习。
template <typename ... Ts, std::size_t ... Is>
auto make_helper (std::index_sequence<Is...> const &)
{ return std::make_tuple(Ts{Is}...); }
template <typename ... Ts>
auto make_derives_tuple ()
{ return make_helper<Ts...>(std::index_sequence_for<Ts...>{}); }
#include <tuple>
#include <utility>
#include <type_traits>
struct Base
{ Base (int) {} };
struct A : public Base
{ A (int id) : Base{id} {} };
struct B : public Base
{ B (int id) : Base{id} {} };
struct C : public Base
{ C (int id) : Base{id} {} };
struct D : public Base
{ D (int id) : Base{id} {} };
template <typename ... Ts, std::size_t ... Is>
auto make_helper (std::index_sequence<Is...> const &)
{ return std::make_tuple(Ts{Is}...); }
template <typename ... Ts>
auto make_derives_tuple ()
{ return make_helper<Ts...>(std::index_sequence_for<Ts...>{}); }
int main()
{
auto t = make_derives_tuple<A, B, C, D>();
using T0 = decltype(t);
using T1 = std::tuple<A, B, C, D>;
static_assert( std::is_same<T0, T1>::value, "!" );
}