2017-01-10 38 views
2

至少我認爲,下面的代碼片段儘可能直接適用於專業化的SFINAE模板:SFINAE專業化沒有得到應用

最後一行是主要點,發生故障的位置。專門的foo模板的定義決定了bar模板的專業化程度,或者我想要的。其他bar專業化可以在其他地方定義,或者也許使用任意類型可以簡單地保持不受支持。據我所知,相同的模式被廣泛建議與enable_if一起使用。

template <typename T> 
struct foo; 

template <> 
struct foo<int> { 
    using type = int; 
}; 

template <typename T, typename use = void> 
struct bar; 

template <typename T> 
struct bar<T, typename foo<T>::type> { 
    using type = typename foo<T>::type; 
}; 

using good = typename foo<int>::type; 
using bad = typename bar<int>::type; 

在g ++中,使用14或17標準,結果如下所示。看起來bar特化沒有得到應用,編譯器正在使用非特定(空)的定義。爲什麼?

$ g++ --std=c++14 special.cpp -o special 
special.cpp:18:32: error: ‘type’ in ‘struct bar<int>’ does not name a type 
using bad = typename bar<int>::type; 
+1

'欄 ::類型><==>酒吧''欄!=條' – 0x499602D2

+0

您實例'欄'。你爲什麼期望編譯器使用除「空」定義之外的其他內容? 「bar」的「非空」專業化甚至不能與''參數進行遠程匹配。 – AnT

回答

4
template <typename T> 
struct bar<T, typename foo<T>::type> { 
    using type = typename foo<T>::type; 
}; 

應該

template <typename T> 
struct bar<T, std::void_t<typename foo<T>::type>> { 
    using type = typename foo<T>::type; 
}; 

use應始終void

這就是爲什麼命名爲AlwaysVoid會更好。 (或使用的東西像Enabler它的作用)

template <typename T, typename AlwaysVoid = void> 
struct bar;