Cha*_*l72 25 c++ templates variadic-templates c++11
stackoverflow上有一个答案(我似乎无法再找到它),它演示了如何在C++ 11中使用可变参数模板在编译时创建静态数组:
template <class T, T... args>
struct array_
{
static const T data[sizeof...(args)];
};
template <class T, T... args>
const T array_<T, args...>::data[sizeof...(args)] = { args... };
Run Code Online (Sandbox Code Playgroud)
可以提供递归元函数以array_使用任意数量的参数进行实例化,然后将这些参数在编译时复制到内部数组中.这是创建元函数以在编译时生成常量数组的有用方法.
但是,一个问题是它依赖于类模板参数来获取填充数组的实际值.这导致一个主要限制:只有积分常数可以用作值模板参数.因此,您无法使用此技术生成自定义类型的数组.
我试着想办法解决这个限制,但不能提出任何建议.有没有办法让这种技术适用于非积分常数?
好吧,您确实可以使用自定义类型(即类)实例填充静态数组,前提是它们可以从整数类型构建(或者可以提供的任何其他类型作为非模板参数,我不会在此枚举).
请看一下下面的例子,我相信这很清楚,可以自我解释:
#include <iostream>
template<typename T>
class my_class
{
public:
my_class(T)
{
//construct
}
void print_something()
{
std::cout << "something\n";
}
};
template<class C, class T, T ... args>
struct array_
{
static C data[sizeof...(args)];
};
template<class C, class T, T ... args>
C array_<C, T, args...>::data[sizeof...(args)] = {C(args)...};
int main()
{
array_<my_class<int> , int, 1, 200, 0, 42>::data[2].print_something();
}
Run Code Online (Sandbox Code Playgroud)
注意:在GCC 4.6下编译得很好
非类型模板参数也可以是指针或引用,只要它们指向或引用具有外部链接的对象。
template<typename T, T& t>
struct ref {
static T&
get() { return t; }
};
int i = 0;
int& ri = ref<int, i>::get(); // ok
static int j = 0;
int& rj = ref<int, j>::get(); // not ok
const int jj = 0; // here, const implies internal linkage; whoops
const int& rjj = ref<const int, jj>::get(); // not ok
extern const int k = 0;
const int& rk = ref<const int, k>::get(); // ok
namespace {
int l = 0;
}
int& rl = ref<int, l>::get(); // ok, and l is specific to the TU
Run Code Online (Sandbox Code Playgroud)
我不认为你真的想用外部引用来初始化元素,因为这最终会导致对象数量增加两倍。您可以从文字初始化数组的元素,但不幸的是您不能使用字符串文字作为模板参数。因此,您需要众所周知的间接层:这很痛苦,因为数组或数组引用不能出现在模板参数列表中(我想这就是字符串文字不能出现的原因):
// Not possible:
// const char* lits[] = { "Hello, ", "World!" };
// lit accepts const char*&, not const char*
// typedef array_<T, lit<lits[0]>, lit<lits[1]>, int_<42> > array;
// instead, but painful:
const char* hello = "Hello";
const char* world = "World!";
typedef array_<T, lit<hello>, lit<world>, int_<42> > array;
/*
* here array::data would be an array of T, size 3,
* initialized from { hello, world, 42 }
*/
Run Code Online (Sandbox Code Playgroud)
我看不出如何在没有 C++0x's 的情况下避免动态初始化constexpr,即使这样也有限制。使用某种元组构建复合初始值设定项(例如从 初始化{ { hello, world, 42 }, ... })作为练习。但这里有一个例子。
| 归档时间: |
|
| 查看次数: |
10480 次 |
| 最近记录: |