为什么左值会明确选择左值引用重载而不是转发引用重载?
Why is an lvalue-ref overload unambiguously chosen over a forwarding-ref overload for an lvalue?
看看这两个重载函数模板:
template <class T>
int foo(T& x) { // #1
return 1;
}
template <class T>
int foo(T&& x) { // #2
return 2;
}
我按以下方式调用foo
:
int i;
foo(i); // calls #1
并且明确选择了重载#1:https://gcc.godbolt.org/z/zchK1zxMW
这似乎是一种正确的行为,但我不明白为什么会发生这种情况(实际上我的代码并不是我所期望的)。
If any candidate is a function template, its specializations are generated using template argument deduction, and such specializations are treated just like non-template functions except where specified otherwise in the tie-breaker rules.
好的,让我们生成专业化。 #1 很简单,它变成 int foo(int& x)
。 #2 适用特殊扣除规则,因为它是转发参考。 i
是一个左值,因此 T
被推导为 int&
并且 T&&
变为 int& &&
,在引用折叠之后变为 int&
,产生结果 int foo(int& x)
。这与 #1 完全相同!
所以我希望看到一个模棱两可的调用,但这并没有发生。谁能解释一下为什么?此处使用什么决胜局来挑选最佳可行功能?
另见related discussion in Slack,有一些想法。
非语言律师的回答是,这个案件有一个决胜规则。
充分理解标准措辞以解码它需要一个简短的书章。但是,当推断出 T&&
与 T&
重载是在左值和其他所有关系之间选择的选项时,T&
获胜。
这样做是为了 (a) 使通用引用起作用,同时 (b) 如果您想单独处理左值引用,则允许您重载它们。
决胜局来自模板函数重载“更专业”的排序规则。对于指针,T*
优于 T
的原因相同,即使 T=Foo*
和 T=Foo
都提供相同的函数参数。对模板参数进行二次排序,T
可以模拟 T*
的事实意味着 T*
更专业(或者更确切地说不是,标准中的措辞很尴尬)。一条额外的规则说明左值 T&
胜过 T&&
在同一部分。
看看这两个重载函数模板:
template <class T>
int foo(T& x) { // #1
return 1;
}
template <class T>
int foo(T&& x) { // #2
return 2;
}
我按以下方式调用foo
:
int i;
foo(i); // calls #1
并且明确选择了重载#1:https://gcc.godbolt.org/z/zchK1zxMW
这似乎是一种正确的行为,但我不明白为什么会发生这种情况(实际上我的代码并不是我所期望的)。
If any candidate is a function template, its specializations are generated using template argument deduction, and such specializations are treated just like non-template functions except where specified otherwise in the tie-breaker rules.
好的,让我们生成专业化。 #1 很简单,它变成 int foo(int& x)
。 #2 适用特殊扣除规则,因为它是转发参考。 i
是一个左值,因此 T
被推导为 int&
并且 T&&
变为 int& &&
,在引用折叠之后变为 int&
,产生结果 int foo(int& x)
。这与 #1 完全相同!
所以我希望看到一个模棱两可的调用,但这并没有发生。谁能解释一下为什么?此处使用什么决胜局来挑选最佳可行功能?
另见related discussion in Slack,有一些想法。
非语言律师的回答是,这个案件有一个决胜规则。
充分理解标准措辞以解码它需要一个简短的书章。但是,当推断出 T&&
与 T&
重载是在左值和其他所有关系之间选择的选项时,T&
获胜。
这样做是为了 (a) 使通用引用起作用,同时 (b) 如果您想单独处理左值引用,则允许您重载它们。
决胜局来自模板函数重载“更专业”的排序规则。对于指针,T*
优于 T
的原因相同,即使 T=Foo*
和 T=Foo
都提供相同的函数参数。对模板参数进行二次排序,T
可以模拟 T*
的事实意味着 T*
更专业(或者更确切地说不是,标准中的措辞很尴尬)。一条额外的规则说明左值 T&
胜过 T&&
在同一部分。