create array
Create static array at compile time
stackoverflow Create static array with variadic templates
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... };
#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();
}
// g++ test.cpp --std=c++11 -pedantic -Wall -Wextra
NOTE:
1、
data的类型: 元素类型为C的数组2、
C(args)...是parameter pack expansion
In C++11 (and especially in C++14), the best way to initialize objects at compile-time is with constexpr constructors, not by playing metagames with the typesystem.
struct MyObject {
int x_, y_;
constexpr MyObject(int x, int y) : x_(x), y_(y) { }
};
const MyObject array[] = { MyObject(1,2), MyObject(3,4) };
You can apply your "generator function" idea here, too, if you really want to:
#include <stdio.h>
#if __cplusplus < 201400
template<size_t ... II> struct integer_sequence
{
typedef integer_sequence type;
};
template<size_t N, size_t ... II> struct make_index_sequence;
template<size_t ... II> struct make_index_sequence<0, II...> : integer_sequence<II...>
{
};
template<size_t N, size_t ... II> struct make_index_sequence: make_index_sequence<N - 1, N - 1, II...>
{
};
#define HACK(x) typename x::type
#else
#include <utility> // the C++14 way of doing things
using std::integer_sequence;
using std::make_index_sequence;
#define HACK(x) x
#endif
struct MyObject
{
int x_, y_;
constexpr MyObject(int x, int y) :
x_(x), y_(y)
{
}
};
template<typename T, int N, T (*Func)(int), typename Indices>
struct GeneratedArrayHelper;
template<typename T, int N, T (*Func)(int), size_t ... i>
struct GeneratedArrayHelper<T, N, Func, integer_sequence<i...>>
{
static const T data[N]; // element i is initialized with Func(i)
};
template<typename T, int N, T (*Func)(int), size_t ... i>
const T GeneratedArrayHelper<T, N, Func, integer_sequence<i...>>::data[N] = { Func(i)... };
template<typename T, int N, T (*Func)(int)>
struct GeneratedArray: GeneratedArrayHelper<T, N, Func, HACK(make_index_sequence<N>)>
{
};
constexpr MyObject newObject(int i)
{
return MyObject(2 * i, 2 * i + 1);
}
int main()
{
for (const MyObject &m : GeneratedArray<MyObject, 5, newObject>::data)
{
printf("%d %d\n", m.x_, m.y_);
}
// Output:
// 0 1
// 2 3
// 4 5
// 6 7
// 8 9
}
// g++ --std=c++11 test.cpp -Wall -Wextra -pedantic
I don't know why Clang 3.5 and GCC 4.8 insist that I put the HACK() macro in there, but they refuse to compile the code without it. Probably I made some dumb mistake and someone can point it out. Also, I'm not confident that all the consts and constexprs are in the best places.
TODO
stackoverflow static compile time table with floating point values
stackoverflow Programmatically create static arrays at compile time in C++