函数返回类型是否会影响重载的选择

Does the function return type affect the choice of an overload?

本文关键字:重载 选择 影响 返回类型 是否 函数      更新时间:2023-10-16

在这篇文章中,建议使用以下方法为定义dump()成员函数的所有类定义operator<<函数:

template <typename T, typename charT>
auto operator<< (std::basic_ostream<charT> & str, const T & t) -> decltype(t.dump(str))
{
    return t.dump(str);
}

为什么这个函数模板不能捕获所有类型,包括那些没有定义dump成员函数的类型?我的意思是,在选择重载时,返回类型是函数签名的一部分吗?

返回类型本身并不重要。当声明对实例化无效时,所提出的技术依赖于SFINAE(替换失败不是错误)来删除重载。也就是说,当编译器尝试用没有可访问的dump(str)成员的类型T实例化上述operator<<()时,decltype(t.dump(str))将无效。它没有失败,而是决定这个重载不起作用,并将其从候选重载集中删除。

一旦收集到候选者,过载解决方案就会选择最佳选项。如果最佳选项是唯一的,则会选择该选项进行调用。如果没有拟合选项,或者有多个最佳匹配,这将是一个错误。

这种行为不是由重载解析规则引起的,而是由模板参数推导规则引起的。特别是归因于SFINAE(即替换失败不是错误)。

在模板参数推导中,编译器会尝试实例化您的函数,但如果输入参数t没有成员函数dump,它不会发出错误,而是会将其视为替换失败,因此不会实例化模板。