具有不同 return 类型的模板实例

Template instances with different return types

根据这份文件,[强调我的]:

The return type of a function has no effect on function overloading, therefore the same function signature with different return type will not be overloaded. Example: if there are two functions: int sum() and float sum(), these two will generate a compile-time error as function overloading is not possible here.

令人惊讶的是 this code snippet 有效!

#include <type_traits>
#include <iostream>

template <typename T>
T foo(){return T{};}

template<>
int foo(){std::cout << "int" << std::endl; return int{};}

template<>
double foo(){std::cout << "double" << std::endl; return double{};}

int main() {
    foo<int>();
    foo<double>();
    foo<bool>();
}

你看,下面的code snippet确实编译不通过(有问题的请看post开头的引文):

#include <type_traits>
#include <iostream>

int foo(){std::cout << "int" << std::endl; return int{};}

double foo(){std::cout << "double" << std::endl; return double{};}

int main() {
}

在第一个片段中,您提供了更通用的主要 函数模板foo<T> 的两个专业化。特别是,您为 T=intT=double 提供了专业化,这意味着我们将拥有彼此不同的 foo<int>foo<double>

所以在第一个片段中没有函数重载,因为名称一开始就不一样。一个是 foo<int>,另一个是 foo<double>

来自function overloading 11.3.5.5

A single name can be used for several different functions in a single scope; this is function overloading.

更重要的是,请注意特化会实例化一个模板; 他们不会超载。因此,特化不会影响函数匹配

考虑以下示例来说明这一点:

示例 1

template <typename T>
T foo(T a, T b){return T{};}

template <>
int foo(int a, int b){return 4;}

int main()
{
    foo(5, 7.0); // error: no matching function for call to ‘foo(int, double)’ 
}

示例 2

template <typename T>
T foo(T a, T b){return T{};}

int foo(int a, int b){return 4;}

int main()
{
    foo(5, 7.0); // works fine 
}

另一方面,在第二个片段中,由于函数名称相同,因此它是函数重载,我们不能仅在 return 类型上重载普通函数。

来自Overloadable declarations

Function declarations that differ only in the return type, the exception specification, or both cannot be overloaded.