这基本上就是我想要的:
struct Item{
int id;
std::string s;
};
template <???>
struct StaticContainer
{
static const std::deque<Item> _items;
};
template <???>
const std::deque<Item> StaticContainer<>::_items {???};
不必是deque
,我只想将可迭代的值列表与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;
}
通常它会让事情变得动态,这就是问题所在,但显然很难让一些动态的东西成为编译时间。 我不想使用继承,多态和类似的运行时,开销诱导方法。
答案 0 :(得分:5)
您不能拥有用户定义的结构的编译时列表。而且你不能拥有任何类型的编译时std::string
。它不是literal type,因此无法在任何constexpr
上下文中使用。
如果您将自己限制为可以在non-type template parameters中使用的类型,则可以使用可变参数模板类型。然后,您不必费心使用运行时容器:
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...>();}
};
但是,请注意,编译器对类型可以具有的模板参数的数量有相当严格的限制。
,你可能不会在键盘上键入它们,但是你可能不会超过这个限制。答案 1 :(得分:2)
使用可变参数模板非类型参数怎么样?
像
这样的东西---编辑:更正(谢谢m.s.)---
--- edit2:添加了数组_items2 ---
#include <deque>
#include <array>
#include <iostream>
struct Item{
int id;
};
template <int ... vals>
struct StaticContainer
{
static const std::deque<Item> _items;
static const std::array<Item, sizeof...(vals)> _items2;
};
template <int ... vals>
const std::deque<Item> StaticContainer<vals...>::_items { {vals}... };
template <int ... vals>
const std::array<Item, sizeof...(vals)> StaticContainer<vals...>::_items2 { { {vals} ... } };
typedef StaticContainer<1, 2, 3> T1;
typedef StaticContainer<0, -1, -2> T2;
int main ()
{
T1 t1;
T2 t2;
//t1 = t2; // Error: incompatible types
std::cout << T1::_items[1].id << std::endl;
std::cout << T2::_items2[0].id << std::endl;
return 0;
}