2014-08-31 4 views
0

Мне нужно создать массив со всеми значениями в диапазоне. Я не могу установить значения после его создания, потому что массив должен быть constexpr.Инициализировать массив по диапазону

template<int FIRST, int LAST> 
struct Foo 
{ 
    static constexpr int array[LAST - FIRST + 1] = ???; 
}; 

Для Exemple Foo<3, 7>::array;

должно быть эквивалентно static constexpr int array[5] = {3, 4, 5, 6, 7};.

Возможно ли это?

ответ

4

Да, это можно сделать на C++ 11. Нет, это некрасиво. Вам по существу необходимо переопределить целые последовательности компиляции C++ 14.

///////////////// Reimplement compile-time integer sequences /////////////////////// 
// There's plenty of better implementations around. 
// This one is similar to libstdc++'s implementation. 
template<class T, T... Ints> 
struct integer_seq { 
    using next = integer_seq<T, Ints..., sizeof...(Ints)>; 
    static constexpr std::size_t size() { return sizeof...(Ints); } 
}; 

template<class T, int Len> 
struct seq_builder{ 
    static_assert(Len > 0, "Length must be nonnegative"); 
    using type = typename seq_builder<T, Len-1>::type::next; 
}; 

template<class T> 
struct seq_builder<T, 0>{ 
    using type = integer_seq<T>; 
}; 

template<class T, int length> 
using make_int_sequence = typename seq_builder<T, length>::type; 

/////////////////// Actual stuff starts here///////////////////////////////// 

template<int FIRST, int LAST, class = make_int_sequence<int, LAST+1-FIRST>> 
struct Foo; 

template<int FIRST, int LAST, int... SEQ> 
struct Foo<FIRST, LAST, integer_seq<int, SEQ...>> 
{ 
    static constexpr int array[sizeof...(SEQ)] = {(FIRST+SEQ)...}; 
}; 

template<int FIRST, int LAST, int... SEQ> 
constexpr int Foo<FIRST, LAST, integer_seq<int, SEQ...>>::array[sizeof...(SEQ)]; 

Demo.

+0

Ничего себе. Я просто хотел скопировать-вставить свой ответ, и код ТОЧНО такой же, как ваш - http://coliru.stacked-crooked.com/view?id=f8812cc2d431f550 – user2030677

+0

@ user2030677 что-то о великих умах что-то :) –

+0

Вау. Хорошая вещь. Я почти не понимаю этот код. :) –

0

Возможно в предложенном стандарте C++14. Я не думаю, что это возможно с C++ 11.

Если вы действительно должны это сделать и не просто иметь несколько таких массивов, которые вы можете жестко закодировать, вы можете прибегнуть к макросам C. По-видимому, есть некоторые библиотеки, которые help you perform loops in macros.

Смежные вопросы