如何根据数组元素自动创建模板类元组?

时间:2015-11-28 09:40:46

标签: c++ arrays c++11 tuples metaprogramming

我有一个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_tupleconstexpr ref之前甚至不是c++14 所以我不确定这是否可行,因为我需要c++11方法。我认为数组的存在是强制性的,因为单独的枚举并不能为这样的事物提供必要的功能。

1 个答案:

答案 0 :(得分:1)

这是一个适用于C ++ 11的解决方案。正如评论中所讨论的那样,使用std::array可以在C ++ 14中使用,其中const访问器是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的内置数组 - 你可以在常量表达式中引用它的元素。我会说,只有在你需要其他东西的数组时才有意义;如果您只需要一个枚举器列表的持有者,那么在这种情况下,可变参数解决方案更简单。对于数组解决方案,您需要类似于C ++ 14的std::index_sequence来扩展数组。