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