【发布时间】:2021-11-22 01:06:58
【问题描述】:
众所周知,只有返回类型不同的普通函数不能在 C++ 中重载。
但是这个限制不适用于重载的函数模板,例如:
int f(auto) { return 1; }
auto f(auto) { return 2; }
所有编译器都接受它,演示:https://gcc.godbolt.org/z/qj73Mzehd
为什么语言对模板有这样的例外?
如果重载函数的返回类型不同,则可以使用强制转换为预期函数类型来选择其中一个函数。令人惊讶的是,即使返回类型实际上相同,Clang 也允许人们解决歧义,例如:
((int(*)(int))f)(3);
选择
int f(auto) { return 1; }
演示:https://gcc.godbolt.org/z/snfvbq1ME
这里是 Clang 错了吗?
【问题讨论】:
-
gcc 不接受它:gcc.godbolt.org/z/j6Enr9h93,我不认为演员应该首先工作。有一些技巧可以将两个
auto函数转换为模板以避免冲突(也许这些是由 clang 和 gcc 应用的),但它们仍然需要通过其他机制来消除歧义。如果您好奇,我可以将可能的模板显式代码放在答案中。 -
@Timo - 这无关紧要。关于签名的一点很重要。我希望这里的人们可以自己从谷壳中分拣出小麦。无论如何,我重新打开了,因为它不是关于专业化,而是模板本身。
-
嗯,这与
auto参数无关。使用模板,函数定义也可以工作 gcc.godbolt.org/z/6dzc65xfa 。仍然 gcc 拒绝演员。 -
@StoryTeller-UnslanderMonica 是的,但是两种情况下的签名(包括模板参数)不一样吗?我认为自动返回类型不能作为模板参数。
-
@Timo - 在实例化主体时推断出,适用于每个专业化。模板一次也没有。
标签: c++ templates language-lawyer c++20 overload-resolution