如果两者都可行,编译器如何确定使用 SFINAE 的函数和标准函数?

use*_*373 4 c++ sfinae c++11

考虑以下代码:

#include <iostream>
#include <type_traits>

template <typename T>
class A
{
public:
    // Allow func to be called if T is the const version of T2
    // e.g., T is 'int const' and T2 is 'int'
    template <typename T2,
              typename = typename std::enable_if<
                                          std::is_same<T, T2 const>::value>::type>
    void func(A<T2> const &)
    {
        std::cout << "Conversion" << std::endl;
    }

    // Allow func to be called for same version of T
    void func(A const &)
    {
        std::cout << "No conversion" << std::endl;
    }
};

int main()
{
    A<int const> a;

    a.func(A<int const>{});

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此代码在使用 GCC-8.3 编译时会编译并生成输出No conversion- 它选择了func不使用std::enable_if. 但是,如果我注释掉 的第二个版本func,它仍然会编译并现在生成输出Conversion。换句话说,这两个版本funcA是执行这种方法可用。鉴于两个重载都是可行的,编译器使用什么特定规则来选择func(A const &)另一个版本 ( func(A<T2> const &))?

Nat*_*ica 7

规则是,如果非函数模板和函数模板特化具有相同的签名,则选择非函数模板而不是模板特化。这可以在[over.match.best]/2 中找到

鉴于这些定义,如果对于所有参数 i,ICSi(F1) 不是比 ICSi(F2) 更差的转换序列,那么一个可行函数 F1 被定义为比另一个可行函数 F2 更好的函数,然后

[...]

  • F1 不是函数模板特化,F2 是函数模板特化 [...]