2016-03-08 36 views
10

考慮下面的代碼:別名模板,局部特殊化和無效參數類型爲void

template<typename F> 
struct S; 

template<typename Ret, typename... Args> 
struct S<Ret(Args...)> { }; 

template<typename... Args> 
using Alias = S<void(Args...)>; 

int main() { 
    S<void(int)> s; 
    Alias<int> alias; 
} 

它正常工作,如預期,既涉及S和一個涉及Alias引擎蓋同一類型下定義線S<void(int)>

現在,考慮以下變化:

int main() { 
    S<void(void)> s; // this line compiles 
    Alias<void> alias; // this line does not 
} 

我希望它來編譯,對於類似於上面提到的那些原因。
不言而喻,它並沒有因爲涉及Alias行的編譯,而不是我的錯誤:

In substitution of 'template using Alias = S [with Args = {void}]'

[...]

error: invalid parameter type 'void'

的問題很簡單:我錯過了這裏?

回答

5

從[dcl.fct],重點煤礦:

A parameter list consisting of a single unnamed parameter of non-dependent type void is equivalent to an empty parameter list. Except for this special case, a parameter shall not have type cvvoid .

在這種情況下,Args...是一個依賴型包,所以void不允許存在。這個想法是在重複一個音符[temp.deduct]:

[ Note: Type deduction may fail for the following reasons:
— [...]
— Attempting to create a function type in which a parameter has a type of void , or in which the return type is a function type or array type.
— [...]
—end note ]

注意S<void(void)>編譯自void(void)非依賴性和相當於void(),所以Ret(Args...)永遠不會得出有參數列表void - 它推斷爲Args...爲空。


至少有一個簡單的解決方法,您可以只寫Alias<>

+0

解決方法很明顯,但是出於同樣的原因它不應該編譯這兩行嗎? 'S '導致一個推論,試圖(好,成功)*創建一個函數類型,其中參數的類型爲'void' *。我錯了嗎? – skypjack

+0

@skypjack剛剛找到我正在尋找的部分。 'void'必須是非依賴的。 – Barry

+0

感謝您的參考。無論如何,也不是'template'中的'Args'類型名稱Ret,typename ... Args> struct S {};'應該遭受同樣問題的依賴類型? – skypjack

相關問題