2012-07-27 20 views
2

我不確定這與sfinae有什麼關係,或者只是與任何模板函數相關的東西。我試圖使用SFINAE基於相應的遊離功能,這又基於在另一種類型的成員函數的所有腦幹使能/禁止的存在以啓用/禁用一個成員函數,所有使用方法描述hereC++ 11樣式SFINAE和模板實例化中的函數可見性

struct S; 

template <typename T> 
inline auto f(S& s, T const& t) 
    -> decltype(t.f(s), void()) 
{ 
    t.f(s); 
} 

struct S 
{ 
    template <typename T> 
    auto f(T const& t) 
     -> decltype(f(*this, t), void()) 
    { 
     f(*this, t); // <------------------------------------------- HERE 
    } 
}; 

struct pass 
{ 
    void f(S&) const 
    { 
     //... 
    } 
}; 

struct fail 
{ 
}; 

int main() 
{ 
    S s; 
    s.f(pass()); // should compile fine 
    //s.f(fail()); // should fail to compile due to absence of f from S 
    return 0; 
} 
然而

GCC 4.7.1使我這個由箭頭標記線:

error: no matching function for call to 'S::f(S&, const pass&)'
note: candidate is:
note: template decltype ((f((* this), t), void())) S::f(const T&)
note: template argument deduction/substitution failed:
note: candidate expects 1 argument, 2 provided

這顯然意味着上述全球f不考慮重載。

爲什麼這樣做,我該怎麼做才能做到這一點?

此外,爲什麼沒有錯誤兩行以上,其中f在decltype中使用類似的方式?

UPDATE

正如@牛米。說,成員函數完全無影子功能,即使他們的簽名不同,所以這裏是一個解決方法,不會破壞ADL的f(不同於@n.m。提供的全名限定)。使免費功能(f_dispatcher)無人看起來(detail),並完全限定其名稱S::f。在該函數調用免費f,讓ADL照顧它從那裏開始,像這樣:

struct S; 

template <typename T> 
inline auto f(S& s, T const& t) 
    -> decltype(t.f(s), void()) 
{ 
    t.f(s); 
} 

namespace detail 
{ 
    template <typename T> 
    inline auto f_dispatcher(S& s, T const& t) 
     -> decltype(f(s, t), void()) 
    { 
     f(s, t); 
    } 
} 

struct S 
{ 
    template <typename T> 
    auto f(T const& t) 
     -> decltype(detail::f_dispatcher(*this, t), void()) 
    { 
     detail::f_dispatcher(*this, t); 
    } 
}; 

struct pass 
{ 
    void f(S&) const 
    { 
     //... 
    } 
}; 

struct fail 
{ 
}; 

int main() 
{ 
    S s; 
    s.f(pass()); // compiles fine 
    //s.f(fail()); // fails to compile due to absence of f from S 
    return 0; 
} 
+0

你不能使用'裏面using聲明的s :: F'呢? – dyp 2014-01-12 12:29:15

+0

@dyp,我可以,但這不會使它在追蹤返回類型中可見。 – 2014-01-12 12:44:38

+0

尾隨返回類型是聲明的一部分,因此它內部的名稱查找將無法找到它所屬的聲明。 – dyp 2014-01-12 13:02:32

回答

6

這有什麼好做SFINAE或模板或C++ 11或ADL。

A成員陰影所有非成員具有相同名稱,無論類型如何。如果您有名爲f的成員,除非您使用限定名稱(例如::f),否則不能引用任何名爲f的非成員。

只需使用::f(*this, t);

+0

哇,顯然我以前從來沒有必要使用同名內部成員之一的免費函數。你確實是對的。但我不能在這裏使用合格的名字,我需要adl來處理它。 – 2012-07-27 20:31:56

+0

@DavidRodríguez-dribeas對'decltype'內部的使用沒有影響。 – 2012-07-27 21:02:44

+0

@DavidRodríguez-dribeas似乎沒有必要,無論如何它是可見的。 – 2012-07-27 21:05:44