【发布时间】:2016-09-02 06:57:12
【问题描述】:
我能接触到的所有编译器都同意这很好:
template <typename Check, typename... T>
auto foo(Check, T...) -> void;
template <typename... T>
auto foo(int, T...) -> void;
int main()
{
foo(7, "");
}
但是,根据 gcc,以下代码(带有无法从函数参数推导出的前导模板参数)是模棱两可的:
template <typename X, typename Check, typename... T>
auto bar(Check, T...) -> void;
template <typename X, typename... T>
auto bar(int, T...) -> void;
int main()
{
bar<void>(7, ""); // ambiguous according to gcc
bar<void>(7); // just fine
}
另一方面,clang、msvc 和 icc 对此非常满意。
哪个编译器是正确的?
参考标准的各个部分首选。
【问题讨论】:
-
这个问题的核心当然是两个重载在实参类型和形参之间都有一个精确的匹配,所以在模板实参的重载中还有一个规则。
-
Gutfeeling 说这不是模棱两可的。附加参数不应有所不同,因为“出于部分排序目的,模板参数可能会保留没有值,前提是它未用于用于部分排序的类型中。”,并且有一个与您的代码匹配的规则示例取模参数包。
-
如果 gcc 接受了仅包含 7 的附加示例,那么我的引用不再解释这种行为差异。
-
@JohannesSchaub-litb 这似乎是正确的。我把它放在一个答案中。
标签: c++ c++11 language-lawyer partial-ordering