struct A { void a() { puts("a"); } };
struct B { void b() { puts("b"); } };
struct C : A, B {};
template <typename T> decltype(&T::a, (void)0) SFINAE(T t) { t.a(); }
template <typename T> decltype(&T::b, (void)0) SFINAE(T t) { t.b(); }
int foo()
{
SFINAE(A{}); // works fine, calls a
SFINAE(B{}); // works fine, calls b
SFINAE(C{}); // compile error
}
上述代码在使用具有
a
和 b
的类型调用 SFINAE 时失败,因此两个模板都有效,导致模糊不清的调用。如何修复上述代码以优先选择模糊情况下的第一个重载?因此,SFINAE(C{})
应该调用 a
。
SFINAE
函数结合起来,变成这样的形式:template <typename T> std::enable_if_t<has_a<T>::value> SFINAE(T t) { t.a(); }
。链接为:https://wandbox.org/permlink/c7M8CFVXyzt3LuFJ - mch