yur*_*hek 2 c++ templates sfinae argument-dependent-lookup c++11
我不确定这与sfinae有什么关系,或者只是与任何模板化函数相关的东西.我试图使用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;
}
Run Code Online (Sandbox Code Playgroud)
但是gcc 4.7.1在箭头标记的行上给了我这个:
错误:没有匹配函数用于调用'S :: f(S&,const pass&)'
注意:候选者是:
注意:模板decltype((f((*this),t),void()))S :: f (const T&)
注意:模板参数推断/替换失败:
注意:候选人需要1个参数,2提供
这显然意味着全局f以上不考虑过载解决.
为什么这样做,我该怎么做才能做到这一点?
另外为什么上面两行没有错误,f在decltype中以类似的方式使用?
UPDATE
正如@nm所说,成员函数完全无阴影函数,即使它们的签名不同,所以这里的解决方法不会破坏ADL f(与@nm建议的全名资格不同).让free function(f_dispatcher)在某个地方没人会看(detail),并在里面完全限定它的名字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;
}
Run Code Online (Sandbox Code Playgroud)
这与SFINAE或模板或C++ 11或ADL无关.
无论类型如何,成员都会隐藏具有相同名称的所有非成员.如果您有一个名为的成员f,则不能引用任何非成员f,除非您使用限定名称(例如::f).
只是用::f(*this, t);.
| 归档时间: |
|
| 查看次数: |
958 次 |
| 最近记录: |