我不確定這與sfinae有什麼關係,或者只是與任何模板函數相關的東西。我試圖使用SFINAE基於相應的遊離功能,這又基於在另一種類型的成員函數的所有腦幹使能/禁止的存在以啓用/禁用一個成員函數,所有使用方法描述here:C++ 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;
}
你不能使用'裏面using聲明的s :: F'呢? – dyp 2014-01-12 12:29:15
@dyp,我可以,但這不會使它在追蹤返回類型中可見。 – 2014-01-12 12:44:38
尾隨返回類型是聲明的一部分,因此它內部的名稱查找將無法找到它所屬的聲明。 – dyp 2014-01-12 13:02:32