2016-04-17 46 views
1

我正在嘗試使用可變參數模板,並得到一個奇怪的問題,我不明白爲什麼會引發錯誤消息。嵌套類中的可變參數模板

template<int v0, int ...Vs> 
class Foo 
{ 
public: 
    template<typename nested = void, 
     typename = void> 
    class Reduce 
    { 
    public: 
     static int const value = v0; 
    }; 

    template<typename nested> 
    class Reduce<nested, 
     typename std::enable_if<0<sizeof...(Vs)>::type> 
    { 
    public: 
     static int const value = v0 + Foo<Vs...>::template Reduce<>::value; 
    }; 
}; 

本準則所帶來的錯誤信息

//example code 
int s = Foo<0,1,2,3,4,5>::Reduce<>::value; 
std::cout << s << std::endl; 

error: incomplete type 'F<5>::Reduce<>' used in nested name specifier 

我插入嵌套虛擬模板參數,因爲在模板嵌套類模板類不能完全專業化。其實我不明白爲什麼編譯器會抱怨一個不完整的類型。
當我改變一個可變的東西

template<int v0, int ...Vs> 
class Reduced 
{ 
public: 
    static int const value = v0 + Reduce<Vs...>::value; 
}; 

template<int v0> 
class Reduced<v0> 
{ 
public: 
    static int const value = v0; 
}; 

template<int v0, int ...Vs> 
class Foo 
{ 
public: 
    class Reduce 
    { 
    public: 
     static int const value = Reduced<v0, Vs...>::value; 
    }; 
}; 

它工作的,但我不知道爲什麼,另一個沒有。任何想法爲什麼編譯器會拋出這個錯誤?感謝幫助。

回答

1

這歸因於C++標準§14.7.3/ P16顯式專業化[temp.expl.spec](重點煤礦)的報價:

在一個顯式特聲明對於類別 模板或名稱空間範圍內出現的成員模板的成員, 成員模板及其某些包含的類模板可能會保留未專用的 ,,但聲明不應明確地爲如果它的封閉類模板 也沒有明確指定,那麼它將專門化一個類成員模板。

也就是說,你不能有專門的類型Foo<int...>::Reduced<>除非Foo封閉類專業以及對象。

您可以通過以下方式修改本:

template<int v0, int ...Vs> 
class Foo { 
public: 
    class Reduce { 
    public: 
    static int const value = v0 + Foo<Vs...>::Reduce::value; 
    }; 
}; 

template<int v0> 
class Foo<v0> { 
public: 
    class Reduce { 
    public: 
    static int const value = v0; 
    }; 
}; 

Live Demo

或者你可以擺脫嵌套類:

template<int v0, int ...Vs> 
class Foo { 
public: 
    static int const value = v0 + Foo<Vs...>::value; 
}; 

template<int v0> 
class Foo<v0> { 
public: 
    static int const value = v0; 
}; 

Live Demo

C++ 17引入摺疊表達式。隨着褶皺的表達,你可以做你想做的只有這樣做:

template<int v0, int ...Vs> 
class Foo { 
public: 
    static const int s = v0 + (Vs + ...); 
}; 

Live Demo

+0

用這種方法我根本不需要模板參數'嵌套',對吧?此外,我喜歡避免Foo類的專業化。因爲在實際使用情況中,它包含更多其他我不想爲專業化實現的東西。 – Feuerteufel

+0

@Feuerteufel是的,模板參數對於這種方法是多餘的。 – 101010

+1

@Feuerteufel我添加了一個編輯檢查,如果它適合你。 – 101010

1
typename std::enable_if<0<sizeof...(Vs)>::type 

您需要將不等式檢查包裝在parens中。

typename std::enable_if< (0 < sizeof...(Vs)) >::type 
+0

不,不解決這個問題。如果解析器無法區分<作爲括號和運算符,我會感到驚訝。 – Feuerteufel