1 回答

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超3個(gè)贊
我認(rèn)為,您所鏈接的論文中對SFINAE的表達(dá)進(jìn)行了很好的解釋。在表達(dá)式上是SFINAE。如果其中的表達(dá)式decltype無效,那么請從重載的VIP休息室中調(diào)用該函數(shù)。您可以在此答案的末尾找到規(guī)范性措詞。
對VC的注意事項(xiàng)++:他們沒有實(shí)現(xiàn)它完全。在簡單的表達(dá)式上,它可能會(huì)起作用,但在其他表達(dá)式上,它將不起作用。有關(guān)失敗的示例,請參見此答案的注釋中的討論。為了簡單起見,這是行不通的:
#include <iostream>
// catch-all case
void test(...)
{
std::cout << "Couldn't call\n";
}
// catch when C is a reference-to-class type and F is a member function pointer
template<class C, class F>
auto test(C c, F f) -> decltype((c.*f)(), void()) // 'C' is reference type
{
std::cout << "Could call on reference\n";
}
// catch when C is a pointer-to-class type and F is a member function pointer
template<class C, class F>
auto test(C c, F f) -> decltype((c->*f)(), void()) // 'C' is pointer type
{
std::cout << "Could call on pointer\n";
}
struct X{
void f(){}
};
int main(){
X x;
test(x, &X::f);
test(&x, &X::f);
test(42, 1337);
}
對于Clang,這將輸出預(yù)期的結(jié)果:
可以用引用
調(diào)用可以用指針
調(diào)用不能調(diào)用
使用MSVC,我得到...好吧,編譯器錯(cuò)誤:
1> src \ main.cpp(20):錯(cuò)誤C2995:“未知類型” test(C,F(xiàn))':功能模板已經(jīng)定義
1> src \ main.cpp(11):參見'test'的聲明
似乎GCC 4.7.1還不能完全完成任務(wù):
source.cpp:代替'模板decltype((c。* f(),void()))test(C,F(xiàn))[C = X *; F =無效(X :: *)()]':
source.cpp:29:17:從這里需要
source.cpp:11:6:錯(cuò)誤:無法將成員指針'f'應(yīng)用于非類類型'X *'的'c'
source.cpp:代替'template decltype((c。* f(),void()))test(C,F(xiàn))[C = int; F = int]':
source.cpp:30:16:從這里需要
source.cpp:11:6:錯(cuò)誤:'f'不能用作成員指針,因?yàn)樗念愋蜑?#39;int'
表達(dá)式SFINAE的常見用法是在定義特征時(shí),例如用于檢查類是否具有某個(gè)成員函數(shù)的特征:
struct has_member_begin_test{
template<class U>
static auto test(U* p) -> decltype(p->begin(), std::true_type());
template<class>
static auto test(...) -> std::false_type;
};
template<class T>
struct has_member_begin
: decltype(has_member_begin_test::test<T>(0)) {};
現(xiàn)場示例。(令人驚訝的是,這再次適用于GCC 4.7.1。)
另請參閱我的答案,該答案在另一種環(huán)境(也稱為無特征)中使用相同的技術(shù)。
規(guī)范用語:
§14.8.2 [temp.deduct]
p6 在模板自變量推導(dǎo)過程中的某些點(diǎn),必須采用利用模板參數(shù)的函數(shù)類型,并用相應(yīng)的模板自變量替換這些模板參數(shù)。當(dāng)將任何顯式指定的模板參數(shù)替換為函數(shù)類型時(shí),此操作在模板參數(shù)推論的開始時(shí)進(jìn)行;當(dāng)替換從默認(rèn)參數(shù)推論或獲得的任何模板參數(shù)時(shí),在模板參數(shù)推論的末尾再次進(jìn)行。
p7 替換發(fā)生在函數(shù)類型和模板參數(shù)聲明中使用的所有類型和表達(dá)式中。表達(dá)式不僅包括常量表達(dá)式(例如出現(xiàn)在數(shù)組范圍內(nèi)或作為非類型模板參數(shù)的常量表達(dá)式),而且還包括,和內(nèi)部 允許非常量表達(dá)式的其他通用表達(dá)式(即,非常量表達(dá)式)。sizeofdecltype
p8如果替換導(dǎo)致無效的類型或表達(dá)式,則類型推導(dǎo)失敗。無效的類型或表達(dá)式是使用替換參數(shù)編寫的格式或表達(dá)式。[...]
- 1 回答
- 0 關(guān)注
- 449 瀏覽
添加回答
舉報(bào)