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

问题描述 投票:0回答:1

请考虑以下代码:

#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;
}

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

请考虑以下代码:#include #include template class A {public://如果T是T2的const版本,则允许调用func // ...

c++ c++11 sfinae
1个回答
3
投票

规则是,如果非功能模板和功能模板专业化具有相同的签名,则将选择非功能模板而不是模板专业化。可以在[over.match.best]/2

中找到

鉴于这些定义,如果对于所有自变量i,ICSi(F1)的转换顺序都不比ICSi(F2)差,则将可行函数F1定义为比另一个可行函数F2更好的函数,然后>]

[...]


-1
投票

您可以阅读有关过载重新分配here的信息。规则相当复杂,但是如果我正确理解了您的问题,您可以通过看到相同的效果

#include<iostream>
template <typename T> void foo(const T& i) { std::cout << "template" ; }
void foo(int i) { std::cout << "perfect match"; }

int main() {
    foo(1);
}
© www.soinside.com 2019 - 2024. All rights reserved.