【发布时间】:2019-10-11 16:15:39
【问题描述】:
使用以下代码 g++ 失败:
template <typename X = int, typename T, typename ...R>
inline void func(const T&, R...) {}
template <typename T>
struct S {};
template <typename X = int, typename T, typename ...R>
inline void func(const S<T>&, R...) {}
int main() {
func(42);
func(S<int>()); // OK
func(S<int>(), 1); // NOK
func<int>(S<int>(), 1); // NOK
}
与:
<source>: In function 'int main()':
<source>:13:21: error: call of overloaded 'func(S<int>, int)' is ambiguous
func(S<int>(), 1); // NOK
^
<source>:13:21: note: candidates are:
<source>:2:17: note: void func(const T&, R ...) [with X = int; T = S<int>; R = {int}]
inline void func(const T&, R...) {}
^
<source>:8:17: note: void func(const S<T>&, R ...) [with X = int; T = int; R = {int}]
inline void func(const S<T>&, R...) {}
^
<source>:14:26: error: call of overloaded 'func(S<int>, int)' is ambiguous
func<int>(S<int>(), 1); // NOK
^
...
可通过 gcc v4.8.1 和 v9.1 重现。使用 clang(v3.0.0 和 v8.0.0)、icc(v13.0.1 和 v19.0.1)、msvc(v19.14 和 v19.20)编译。
代码有效还是 gcc 中的错误?
编辑:谢谢大家,您的反馈对我很有帮助。仅供参考,bug 90642 已提交;期待一个明确的答案。
【问题讨论】:
-
C++ 中没有函数模板的部分特化。只有完全专业化和重载。
-
你没有专门化这个函数,你重载了它。并且编译器无法区分您传递的参数的两个重载。
-
谢谢,我的意思是 gcc 没有专业化。我明白你的意思,但是为什么 func(S
()) 可以而 func(S (), 1) 不行? -
fti clang 编译 gcc 不会,直播:godbolt.org/z/p1HsRC
-
对我来说看起来像一个错误。如果您删除无用和无关紧要的
typename X = int,它会编译。没有理由为什么一个应该有效而另一个不应该。
标签: c++ c++11 gcc language-lawyer variadic-templates