C++ c++;模板重构/泛化

C++ c++;模板重构/泛化,c++,c++11,C++,C++11,这段代码是否可以通用化,这样我就可以拥有数量可变的类型/参数 (我确实更喜欢将函数保留在结构之外,以保持代码更干净。) unsigned int const maxID=2^8; typedef无符号整数ID; 模板 结构SOA{ T1 a1[maxID]; t2a2[maxID]; t3a3[maxID]; T4 a4[maxID]; T5 a5[maxID]; T6 a6[maxID]; ID currentMaxID=0; }; 模板 ID附加值(SOA和SOA、T1 a1、T2 a2、T

这段代码是否可以通用化,这样我就可以拥有数量可变的类型/参数

(我确实更喜欢将函数保留在结构之外,以保持代码更干净。)

unsigned int const maxID=2^8;
typedef无符号整数ID;
模板
结构SOA{
T1 a1[maxID];
t2a2[maxID];
t3a3[maxID];
T4 a4[maxID];
T5 a5[maxID];
T6 a6[maxID];
ID currentMaxID=0;
};
模板
ID附加值(SOA和SOA、T1 a1、T2 a2、T3 a3、T4 a4、T5 a5、T6 a6){
soa.a1[soa.currentMaxID]=a1;
soa.a2[soa.currentMaxID]=a2;
soa.a3[soa.currentMaxID]=a3;
soa.a4[soa.currentMaxID]=a4;
soa.a5[soa.currentMaxID]=a5;
soa.a6[soa.currentMaxID]=a6;
返回soa.currentMaxID++;
}
模板
ID移除实体(SOA和SOA,ID实体ID){
soa.currentMaxID--;
soa.a1[entityID]=soa.a1[soa.currentMaxID];
soa.a2[entityID]=soa.a2[soa.currentMaxID];
soa.a3[entityID]=soa.a3[soa.currentMaxID];
soa.a4[entityID]=soa.a4[soa.currentMaxID];
soa.a5[entityID]=soa.a5[soa.currentMaxID];
soa.a6[entityID]=soa.a6[soa.currentMaxID];
}

实际工作。首先,助手
详细信息

namespace details {
  template <typename... Ts, unsigned... Is>
  ID AddEntity(indexes<Is...>, SOA<Ts...>& soa, decay_t<Ts> const&... ts) {
    int unused[] = { ( (std::get<Is>(soa.a)[soa.currentMaxID] = ts ), void(), 0 )..., 0 };
    (void)(unused); // just blocks warnings
    return soa.currentMaxID++;
  }
  template <typename... Ts, unsigned... Is>
  void RemoveEntity(indexes<Is...>, SOA<Ts...>& soa, ID entityID) {
    --soa.currentMaxID;
    int unused[] = {
      ( (std::get<Is>(soa.a)[entityId] = std::get<Is>(soa.a)[soa.currentMaxID] ),
      void(), 0 )..., 0
    };
    (void)(unused); // just blocks warnings
  }
}
名称空间详细信息{
模板
ID加法(索引、SOA和SOA、衰减常数和…ts){
int unused[]={((std::get(soa.a)[soa.currentMaxID]=ts),void(),0)…,0};
(void)(未使用);//仅阻止警告
返回soa.currentMaxID++;
}
模板
void removentity(索引、SOA和SOA、ID entityID){
--soa.currentMaxID;
int未使用[]={
((std::get(soa.a)[entityId]=std::get(soa.a)[soa.currentMaxID]),
void(),0)…,0
};
(void)(未使用);//仅阻止警告
}
}
它使用数组做很多事情。然后:

template <typename... Ts>
ID AddEntity(SOA<Ts...>& soa, decay_t<Ts> const&... ts) {
  return details::AddEntity( make_indexes_t< sizeof...(Ts) >{}, soa, ts... );
}

template <typename...Ts>
void RemoveEntity(SOA<Ts...>& soa, ID entityID) {
  details::RemoveEntity( make_indexes_t< sizeof...(Ts) >{}, soa, entityID );
}
模板
ID加法(SOA和SOA,衰减常数和…ts){
返回详细信息::AddEntity(make_index_t{},soa,Ts…);
}
模板
无效删除实体(SOA和SOA,ID entityID){
详细信息::RemoveEntity(使索引{},soa,entityID);
}


请注意,我支持空集合
Ts..

您可以将其存储为元组数组。您能告诉我如何执行此操作吗?类似于
template struct SOA{std::tuple a[maxID];}类型在内存中必须是线性的。像T1…T1,T2…T2等,将std::tuple a[maxID];不要像T1,T2,T3那样排列它们。。。T1、T2、T3?一个
std::tuple
?我怎样才能支持Ts的空集合?当我试图编译你的代码时,我在详细名称空间中得到错误,它位于。。。抱歉,我不能让你的代码编译。我得到关于Ts的错误,并且位于详细信息命名空间和中。好的,它现在可以编译了。此行不编译:int unused[]={(std::get(soa)[soa.currentMaxID]=ts),void(),0)…,0};还有这一行:int unused[]={(std::get(soa)[soa.entityId]=std::get(soa)[soa.currentMaxID]),void(),0)…,0};
template<unsigned...>struct indexes{using type=indexes;};
template<unsigned Max, unsigned...Is>struct make_indexes:make_indexes<Max-1,Max-1,Is...>{};
template<unsigned...Is>struct make_indexes<0,Is...>:indexes<Is...>{};
template<unsigned Max>using make_indexes_t=typename make_indexes<Max>::type;
template<class T>using decay_t=typename std::decay<T>::type;
namespace details {
  template <typename... Ts, unsigned... Is>
  ID AddEntity(indexes<Is...>, SOA<Ts...>& soa, decay_t<Ts> const&... ts) {
    int unused[] = { ( (std::get<Is>(soa.a)[soa.currentMaxID] = ts ), void(), 0 )..., 0 };
    (void)(unused); // just blocks warnings
    return soa.currentMaxID++;
  }
  template <typename... Ts, unsigned... Is>
  void RemoveEntity(indexes<Is...>, SOA<Ts...>& soa, ID entityID) {
    --soa.currentMaxID;
    int unused[] = {
      ( (std::get<Is>(soa.a)[entityId] = std::get<Is>(soa.a)[soa.currentMaxID] ),
      void(), 0 )..., 0
    };
    (void)(unused); // just blocks warnings
  }
}
template <typename... Ts>
ID AddEntity(SOA<Ts...>& soa, decay_t<Ts> const&... ts) {
  return details::AddEntity( make_indexes_t< sizeof...(Ts) >{}, soa, ts... );
}

template <typename...Ts>
void RemoveEntity(SOA<Ts...>& soa, ID entityID) {
  details::RemoveEntity( make_indexes_t< sizeof...(Ts) >{}, soa, entityID );
}