【发布时间】:2017-05-01 18:03:09
【问题描述】:
具有以下 3 个重载
template <class T> auto foo() { return 1; }
template <class T> int foo() { return 2; }
template <class T> T foo() { return 3; }
下面的格式不正确吗?
static_cast<int(*)()>(&foo<int>)();
Clang 选择重载 #2,而 gcc 无法编译 (Demo)
删除重载 #1 时,双方同意选择重载 #2 (Demo)。
移除重载#2时,gcc选择重载#1,clang编译失败(Demo)
【问题讨论】:
-
在同一个翻译单元中定义 1 和 2 不是违反 ODR 吗?
-
如果“auto”被翻译成“int”,那么#1 和#2 是一样的,是吗?不是首选候选人。 Clang 似乎认为 #2 比 #1 更专业,而 #1 和 #3 是相同的专业化;再次模棱两可的选择。我会说 gcc 是对的,而 Clang 是错的,因为“auto”不应该参与重载决议。
-
@user657267 返回类型是函数模板签名的一部分。上面的声明提供了不同的declared返回类型,所以签名不同。实际返回类型是否一致是无关紧要的。
-
好问题。 +1
标签: c++ templates c++14 language-lawyer overloading