C 11样式SFINAE和模板实例化时的功能可见性
作者:互联网
我不确定这与sfinae有什么关系,或者只是与任何模板化函数相关的东西.我试图使用sfinae根据相应的自由函数的存在来启用/禁用成员函数,而后者又基于另一种类型的成员函数的存在来启用/禁用,所有使用描述的方法here:
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
作为@ n.m.说,成员函数完全没有阴影自由函数,即使它们的签名不同,所以这里的解决方法不会破坏AD的ADL(与@n.m建议的全名资格不同).使自由函数(f_dispatcher)在任何人看不到(细节),并在S :: f中完全限定其名称.在该函数中,调用free 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;
}
解决方法:
这与SFINAE或模板或C 11或ADL无关.
无论类型如何,成员都会隐藏具有相同名称的所有非成员.如果您有一个名为f的成员,则除非使用限定名称(例如:: f),否则不能引用任何名为f的非成员.
只需使用:: f(* this,t);.
标签:c,c11,templates,sfinae,argument-dependent-lookup 来源: https://codeday.me/bug/20191002/1844408.html