2016-12-24 91 views
0

我想用C++(11/14)實現fortran的reshape函數,我設計了一個函數。該功能接受兩個std::initializer_list。第一個initializer_list給出了我用來初始化一個D維數組的初始值。第二個initializer_list給出了數組的每個維度的大小。 我寫了一個草案這樣在編譯時得到`std :: initializer_list`的大小

template<int D, typename T> 
auto forreshape(const std::initializer_list<T> & values, const std::initializer_list<int> & shape) 
{ 
    // some irrelevant codes to calculate lbound 
    return for1array_gen<T, D>(lbound, shape, values); // returns D dimension array fornarray<T, D> 
} 
int main(){ 
    auto reshaped_array = forreshape<2>({1, 2, 3, 4, 5, 6}, {2, 3}); 
} 

實現需要給定的非類型模板參數int D,但我想要的東西,而不D,像forreshape({1, 2, 3, 4, 5, 6}, {2, 3});。 起初我想用std::initializer_list<T>::size,但是從static-assert-on-initializer-listsize我知道它不起作用。環顧四周,我發現how-to-cause-a-compile-time-error-based-on-the-size-of-an-initializer-list,但它沒有幫助我的情況。 我認爲編譯器可以得到足夠的信息並自動推斷出int D的值,但我不知道如何。也許這是一個壞主意,使用std::initializer_list?我完全失去了這裏

+3

'的std :: initializer_list <> ::尺寸()''是在constexpr' C++ 14。有什麼問題..? – ildjarn

+0

我使用MSVC 2015,編譯時出現C2131錯誤, – calvin

+0

MSVC 2015不支持C++ 14'constexpr'(MSVC 2017);您將有效地需要該編譯器的C++ 11答案。 – ildjarn

回答

3

也許這是一個壞主意,使用std::initializer_list

我是這麼認爲的。考慮

std::initializer_list<int> t; 
std::initializer_list<int> a = {1,2,3}; 
std::initializer_list<int> b = {2,3}; 
if (rand() > 42) 
    t = a; 
else 
    t = b; 
auto reshaped_array = forreshape({1,2,3,4,5,6}, t); 

在上面的例子中,它只是不可能在編譯時就知道t.size()

但您可以通過使用對C風格數組的引用,讓編譯器推斷初始化程序列表的長度,這要歸功於CWG 1591

forreshape定義將如下所示:

template<int D, typename T> 
auto forreshape(const std::initializer_list<T> & values, const int (&shape)[D]) 
{ 
    // use D... 
} 
相關問題