如何创建一个初始化具有特定值的成员容器的编译时静态类类型?

Vio*_*ffe 5 c++ templates c++11

这基本上就是我想要的:

struct Item{
   int id;
   std::string s;   
};

template <???>
struct StaticContainer
{
    static const std::deque<Item> _items;
};

template <???>
const std::deque<Item> StaticContainer<>::_items {???};
Run Code Online (Sandbox Code Playgroud)

不必是a deque,我只想将可迭代的值列表与a关联起来type.所以我可以做类似的事情

typedef StaticContainer<{{1, "a", {2, "b"}, {3, "c"}}> T1;
typedef StaticContainer<{{0, "e"}, {-1, "f"}, {-2, "g"}}> T2;

int main() {
   T1 t1;
   T2 t2;
   t1 = t2; // Error: incompatible types

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

通常情况下,它会让事情变得动态,但是很明显,要让一些动态的东西成为编译时也是如此.我不想使用继承,多态和类似的运行时,开销诱导方法.

Nic*_*las 5

您不能拥有用户定义的结构的编译时列表.而且你不能拥有std::string 任何类型的编译时间.它不是文字类型,因此不能在任何constexpr上下文中使用.

如果将自己限制为可以在非类型模板参数中使用的类型,则可以使用可变参数模板类型.然后,您不必费心运行时容器:

template<typename T, T ...ts>
struct value_list
{
    //Not the most efficient way to get a value.
    template<int ix>
    static constexpr auto get()
    { return std::get<ix>(std::make_tuple(ts...)); }

    //Get a general container
    template<typename Container>
    static auto get_container() {return Container{ts...};}

    //Get an array, appropriately sized.
    static constexpr auto get_array()
    { return std::array<T, sizeof...(ts)>{ts...}; }

    //Manipulators. Types are static, so they must return
    //new types with the new values.
    template<T new_val>
    constexpr auto push_back()
    {return value_list<T, ts..., new_val>();}

    template<T new_val>
    constexpr auto push_front()
    {return value_list<T, new_val, ts...>();}
};
Run Code Online (Sandbox Code Playgroud)

实例.

但是,请注意,编译器对类型可以具有的模板参数的数量有相当严格的限制.您可能不会通过在键盘上键入它们来超过此限制,但您可以通过键盘构建它们.