有点像我的延续上一个问题 https://stackoverflow.com/questions/11694970/c11-style-sfinae-and-function-visibility-on-template-instantiation。我得到的是一堆形成 sfinae 依赖链的函数,如下所示(让“A -> B”表示法意味着 A 的存在取决于 B 的存在):
S::f_base -> S::f -> ns::f_ -> f -> T::f
其中 T 是模板参数。它的实现就像this http://liveworkspace.org/code/9780ef0aa9b85e6464dbf1538ab4ae25:
#include <utility>
struct S;
template <typename T>
auto f(S& s, T const& t) -> decltype(t.f(s), void())
{
t.f(s);
}
namespace ns
{
template <typename T>
auto f_(S& s, T const& t) -> decltype(f(s, t), void())
{
f(s, t);
}
}
struct S
{
template <typename T>
auto f(T const& t) -> decltype(ns::f_(std::declval<S&>(), t), void())
{
ns::f_(*this, t);
}
template <typename T>
auto f_base(T const* t_ptr) -> decltype(f(*t_ptr), void())
{
f(*t_ptr);
}
};
struct pass
{
void f(S&) const
{
}
};
struct fail
{
};
int main()
{
S s;
s.f(pass()); // compiles
//s.f(fail()); // doesn't compile
return 0;
}
并按预期工作。当我尝试移动定义时,问题就出现了S::f
and S::f_base
在班级之外,例如so http://liveworkspace.org/code/f54caec1993057b576c04d0608b22cdf:
#include <utility>
struct S;
template <typename T>
auto f(S& s, T const& t) -> decltype(t.f(s), void())
{
t.f(s);
}
namespace ns
{
template <typename T>
auto f_(S& s, T const& t) -> decltype(f(s, t), void())
{
f(s, t);
}
}
struct S
{
template <typename T>
auto f(T const& t) -> decltype(ns::f_(std::declval<S&>(), t), void());
template <typename T>
auto f_base(T const* t_ptr) -> decltype(f(*t_ptr), void());
};
template <typename T>
auto S::f(T const& t) -> decltype(ns::f_(std::declval<S&>(), t), void())
{
ns::f_(*this, t);
}
template <typename T>
auto S::f_base(T const* t_ptr) -> decltype(f(*t_ptr), void()) // <---- HERE ---
{
f(*t_ptr);
}
int main()
{
return 0;
}
在箭头标记的线上GCC 4.7.1
表达了不满:
错误:'decltype ((((S*)0)->S::f((* t_ptr)), void())) S::f_base(const T*)' 的原型与类 ' 中的任何原型都不匹配S'
错误:候选者是: template decltype ((((S*)this)->S::f((* t_ptr)), void())) S::f_base(const T*)
我试图明确指定哪个f
我正在使用f_base
通过在它前面(在声明和定义中)加上std::declval<S&>().
,但错误仍然存在。
我知道我可以像这样修改依赖关系图:
S::f_base ->
-> ns::f_ -> f -> T::f
S::f ->
to make S::f_base
取决于ns::f_
随着S::f
,但是有没有办法用第一个依赖图来做到这一点?