該代碼失敗在大多數編譯器來編譯,但起初我直覺預期SFINAE保護我:SFINAE,演繹與實例
:
typedef void (*A)();
template < typename T >
struct a_metafun { typedef typename T::type type; };
template < typename T >
typename a_metafun<T>::type f(T) {}
template < typename T>
void f(T(*)()) {}
int main() { f(A()); }
我可以以至少兩種方式解決這個問題1)改變的「metafun」 F(定義),以:
template < typename T > typename T::type f(T) {}
2)界定「a_metafun」,使得它分析T和具有類型,如果T具有一個,並且不我f,將它不...但沒有實例化錯誤兩種方式:
BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
typedef < template T, bool = has_type<T>::value >
struct a_metafun { };
typedef < template T >
struct a_metafun<T, true> { typedef typename T::type type };
在觀看14.8.2(C++ 03),它看起來對我來說,它僅指定了下情況SFINAE可以申請什麼。有更好的地方看嗎?在已經推導出的模板的實例化中失敗,即使在扣除另一個模板的過程中,似乎也不包括在這個列表中。
我已經採取了另一個解釋是什麼使得這個非法的方向是a_metafun的演繹已經發生並且其內部的實例化是導致錯誤的原因。 SFINAE在實例化過程中不適用,但僅在扣除過程中使用,或者我錯了嗎?但在第二種情況下,a_metafun正確,並且實例化良好,但它內部沒有「類型」定義,這意味着嘗試實例化它的模板由於替換而失敗。
基本上我想知道標準中的什麼指定了我目睹的行爲。我試過的每一個編譯器都會抱怨,甚至是冒險島。我認爲他們這樣做是正確的,我只是不完全確定爲什麼。
那麼,專家......那是什麼?爲什麼類型的實例化,即使在f()中的演繹上下文中導致錯誤而不是SFINAE排除?
我認爲,應該在C++ 11失敗,而不是在C++ 03雖然。 SFINAE規則(或者*措辭*)在C++ 11中略有改變。 – Nawaz