2014-08-31 70 views
0

我需要创建一个数组,范围内的所有值。创建后无法设置值,因为数组必须是constexpr。初始化数组的范围

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

对于为例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 2014-08-31 19:22:15

+0

@ user2030677关于伟大的思想的东西:) – 2014-08-31 19:23:20

+0

哇。好东西。我几乎不懂这个代码。 :) – 2014-08-31 22:20:33

0

在建议的C++14标准中是可能的。我不认为用C++ 11是可能的。

如果你真的必须这样做,而不是只有几个你可以硬编码的这样的数组,你可以求助于C宏。显然有一些库,help you perform loops in macros