2012-10-27 87 views
1
#include <iostream> 
#include <array> 
using namespace std; 

constexpr int N = 10; 
constexpr int f(int x) { return x*2; } 

typedef array<int, N> A; 

template<int... i> struct F { constexpr A f() { return A{{ f(i)... }}; } }; 

template<class X, class Y> struct C; 
template<int... i, int... j> 
struct C<F<i...>, F<j...>> : F<i..., (sizeof...(i)+j)...> {}; 

template<int n> struct S : C<S<n/2>, S<n-n/2>> {}; // <--- HERE 
template<> struct S<1> : F<0> {}; 

constexpr auto X = S<N>::f(); 

int main() 
{ 
     cout << X[3] << endl; 
} 

我越來越:C++ 11:解決方法使用此不完整類型錯誤?

test.cpp:15:24: error: invalid use of incomplete type ‘struct C<S<5>, S<5> >’ 

我懷疑這是因爲S的定義是使用本身作爲一個基類。 (正確嗎?)

解決此問題的最佳方法是什麼?

更新:

這裏是固定的版本:

#include <iostream> 
#include <array> 
using namespace std; 

constexpr int N = 10; 
constexpr int f(int x) { return x*2; } 

typedef array<int, N> A; 

template<int... i> struct F { static constexpr A f() { return A{{ ::f(i)... }}; } }; 

template<class A, class B> struct C {}; 
template<int... i, int... j> struct C<F<i...>, F<j...>> : F<i..., (sizeof...(i)+j)...> 
{ 
     using T = F<i..., (sizeof...(i)+j)...>; 
}; 

template<int n> struct S : C<typename S<n/2>::T, typename S<n-n/2>::T> {}; 
template<> struct S<1> : F<0> { using T = F<0>; }; 

constexpr auto X = S<N>::f(); 

int main() 
{ 
     cout << X[3] << endl; 
} 
+0

相關:http://stackoverflow.com/questions/13072359/c11-compile-time-array-with-logarithmic-evaluation-depth –

+0

犯規編譯。即使C++ 11也不允許在很多地方使用省略號。 –

+0

@ööTiib:我知道它不能編譯,我顯示編譯器錯誤。它與橢圓無關。 –

回答

2

定義C,而不是僅僅宣佈它。

template<class X, class Y> struct C {}; 

在你使用它的偏特不匹配的地方, 主模板實例,這只是一個聲明。

您可能想知道爲什麼沒有考慮專業化:專業化不考慮轉化,而只是靜態類型。這就是爲什麼他們與繼承非常不相容。

+0

嗯,這很糟糕。不管怎麼說,還是要謝謝你。 –

+0

@ AndrewTomazos-Fathomling我冥想了你在這裏想要做的事情,但對我來說沒有多大意義。該代碼實際上試圖實現什麼?我可以弄清楚'F'和'C',但是'S'的目的不在我身上。 – pmr

+0

請參閱:http://stackoverflow.com/questions/13072359/c11-compile-time-array-with-logarithmic-evaluation-depth –

0

你可以委託S::f而不是繼承嗎?

template<int n> struct S { 
    constexpr A f() { return C<S<n/2>, S<n-n/2>>::f(); } 
}; 
+0

'C ,S >'需要綁定到專業化'C ,F >',這不會因爲模板專業化不考慮繼承。 –

相關問題