如何基于数组的元素自动创建模板类的元组

How to automate creation of tuples of template classes based on elements of an array?

本文关键字:建模 元组 创建 何基于 数组 元素      更新时间:2023-10-16

我有一个std::array,它填充了枚举的所有类型。我想实现基于元组的关于这个。

class CompBase
{
public:
    enum CompType{
        INPUT,
        GRAPHICS
        // ( + 5-10 additional types)
    };
    static const std::array<CompType, 2> compTypeArr;
};
const std::array<CompBase::CompType, 2> CompBase::compTypeArr =
{
    CompBase::INPUT,
    CompBase::GRAPHICS
};
template<CompBase::CompType compType_e>
class CompHolder {}; // owns one component
template<CompBase::CompType compType_e>
class CompContainer {}; // references N components
class CompInterface
{
    // ...
private:
    std::tuple // I want to automate this,
    <
        CompHolder<CompBase::INPUT>,
        CompHolder<CompBase::GRAPHICS>
    > compHolders;
};
class CompHandler
{
    // ...
private:
    std::tuple // and this process, based on the predefined array
    <
        CompCont<CompBase::INPUT>,
        CompCont<CompBase::GRAPHICS>
    > compContainers;
};

据我所知,std::make_tuplec++14引用之前甚至不是constexpr所以我不确定这是否可能,因为我需要一个c++11方法。数组的存在我认为是强制性的,因为单独的枚举并不能为类似的事情提供必要的功能。

这里有一个在C++11中工作的解决方案。正如在评论中所讨论的,使用std::array将在C++14中工作,其中它的常量访问器被设置为constexpr

#include <tuple>
#include <type_traits>
#include <iostream>
class CompBase
{
public:
   enum CompType {
      INPUT,
      GRAPHICS
      // ( + 5-10 additional types)
   };
};
template<CompBase::CompType...> struct CTLHelper;
using CompTypeList = CTLHelper<
   CompBase::INPUT,
   CompBase::GRAPHICS
>;
template<template<CompBase::CompType> class, class> struct CompTupleMaker;
template<template<CompBase::CompType> class H, CompBase::CompType... Es> 
struct CompTupleMaker<H, CTLHelper<Es...>>
{
   using type = std::tuple<H<Es>...>;
};
template<CompBase::CompType compType_e>
class CompHolder {}; // owns one component
template<CompBase::CompType compType_e>
class CompContainer {}; // references N components
using CompHolderTuple = CompTupleMaker<CompHolder, CompTypeList>::type;
using CompContainerTuple = CompTupleMaker<CompContainer, CompTypeList>::type;
class CompInterface
{
   // ...
private:
   CompHolderTuple compHolders;
};
class CompHandler
{
   // ...
private:
   CompContainerTuple compContainers;
};

int main()
{
   // just a quick check
   std::cout << std::is_same<CompHolderTuple, std::tuple<CompHolder<CompBase::INPUT>, CompHolder<CompBase::GRAPHICS>>>::value << 'n';
}

如果在C++11中的数组中确实需要这些枚举器,可以使用声明为constexpr的内置数组——可以在常量表达式中引用其元素。我想说,只有当你也需要数组来做其他事情时,这才有意义;如果您只需要一个枚举器列表的持有者,那么在这种情况下,variadic解决方案会更简单。对于阵列解决方案,您需要类似于C++14的std::index_sequence的东西来扩展阵列。