GCC 无法解析带有默认参数和以下参数包的方法调用
GCC can not resolve method call with defaulted parameter and following parameter pack
是否允许GCC因为歧义拒绝下面的代码?对我来说,它看起来像一个错误。
它与 msvc、clang 和 icc 编译良好。
看这里:https://godbolt.org/z/9fsnhx
#include <iostream>
class A
{
public:
template<typename T>
void Foo(int={}){
std::cout << "A";
}
template<
typename... T
,typename... Args
>
void Foo(int={}, Args&&... args)
{
std::cout << "B";
}
};
int main()
{
A a;
a.Foo<int>();
}
我认为这是一个 gcc 错误。正如 在评论中指出的那样,如果您为默认参数提供参数,gcc 接受 - 但在这种情况下这应该是无关紧要的。
这里要指出的相关规则是[temp.deduct.partial],第3段:
The types used to determine the ordering depend on the context in which the partial ordering is done:
- In the context of a function call, the types used are those function parameter types for which the function call has arguments.138
(脚注说):[=23=]
Default arguments are not considered to be arguments in this context; they only become arguments after a function has been selected.
第 11 段:
If, after considering the above, function template F is at least as specialized as function template G and vice-versa, and if G has a trailing function parameter pack for which F does not have a corresponding parameter, and if F does not have a trailing function parameter pack, then F is more specialized than G.
第 12 段:
In most cases, deduction fails if not all template parameters have values, but for partial ordering purposes a template parameter may remain without a value provided it is not used in the types being used for partial ordering. [ Note: A template parameter used in a non-deduced context is considered used. — end note ] [ Example:
template <class T> T f(int); // #1
template <class T, class U> T f(U); // #2
void g() {
f<int>(1); // calls #1
}
— end example ]
简而言之,这里考虑偏序时:
默认参数无关紧要,我们只考虑将int
作为第一个参数的两个函数模板。
第一次重载中的T
和第二次重载中的T...
也没有关系。它们 not 在用于部分排序的类型集中,它们不是函数的参数。这类似于第 12 段中的示例,其中同样名为 T
的模板参数也不起作用。
所以基本上我们在以下时间点餐:
void Foo(int);
template <typename... Args> void Foo(int, Args&&...);
这是一个非常简单的案例,其中第一个更专业。 gcc 弄错了 - 我提交了 96602.
是否允许GCC因为歧义拒绝下面的代码?对我来说,它看起来像一个错误。 它与 msvc、clang 和 icc 编译良好。
看这里:https://godbolt.org/z/9fsnhx
#include <iostream>
class A
{
public:
template<typename T>
void Foo(int={}){
std::cout << "A";
}
template<
typename... T
,typename... Args
>
void Foo(int={}, Args&&... args)
{
std::cout << "B";
}
};
int main()
{
A a;
a.Foo<int>();
}
我认为这是一个 gcc 错误。正如
这里要指出的相关规则是[temp.deduct.partial],第3段:
The types used to determine the ordering depend on the context in which the partial ordering is done:
- In the context of a function call, the types used are those function parameter types for which the function call has arguments.138
(脚注说):[=23=]
Default arguments are not considered to be arguments in this context; they only become arguments after a function has been selected.
第 11 段:
If, after considering the above, function template F is at least as specialized as function template G and vice-versa, and if G has a trailing function parameter pack for which F does not have a corresponding parameter, and if F does not have a trailing function parameter pack, then F is more specialized than G.
第 12 段:
In most cases, deduction fails if not all template parameters have values, but for partial ordering purposes a template parameter may remain without a value provided it is not used in the types being used for partial ordering. [ Note: A template parameter used in a non-deduced context is considered used. — end note ] [ Example:
template <class T> T f(int); // #1 template <class T, class U> T f(U); // #2 void g() { f<int>(1); // calls #1 }
— end example ]
简而言之,这里考虑偏序时:
默认参数无关紧要,我们只考虑将
int
作为第一个参数的两个函数模板。第一次重载中的
T
和第二次重载中的T...
也没有关系。它们 not 在用于部分排序的类型集中,它们不是函数的参数。这类似于第 12 段中的示例,其中同样名为T
的模板参数也不起作用。
所以基本上我们在以下时间点餐:
void Foo(int);
template <typename... Args> void Foo(int, Args&&...);
这是一个非常简单的案例,其中第一个更专业。 gcc 弄错了 - 我提交了 96602.