c++ - 当多个重载通过 SFINAE 时创建首选重载

标签 c++ templates c++14

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
}

当使用具有 ab 的类型调用 SFINAE 时,上述代码失败,从而使两个模板都有效,从而导致调用不明确。在模棱两可的情况下,如何修复上述代码以更喜欢第一个重载?所以 SFINAE(C{}) 应该调用 a

最佳答案

您可以通过引入转换来消除调用的歧义:

template <typename T> decltype(&T::a, (void)0) impl(T t, int) { t.a(); }
template <typename T> decltype(&T::b, (void)0) impl(T t, unsigned) { t.b(); }

template <typename T> void SFINAE(T && t) { impl(std::forward<T>(t), 42); }

传递 int 类型的 42,编译器将选择第一个重载作为更好的匹配。

Demo

关于c++ - 当多个重载通过 SFINAE 时创建首选重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56987763/

相关文章:

c++ - Qt focusInEvent() 只为键盘获取焦点

c++ - 为什么返回值优化发生在这里

c++ - 出于测试目的故意让 C++ 程序运行得更慢?

c++ - 在流畅的界面中避免不必要的模板实例化

c++ - 我可以编写一个返回函数的函数类型吗?

c++ - 如何在 C++ 中存储泛型元素数组?

c++ - 类模板的 C++1 7's "模板参数推导可以推导局部类型吗?

python - CSS 文件未应用于瓶中的 TPL

c++ - 编译器是否默认生成构造函数constexpr?

c++ - 具有编译时初始化的常量数据容器类