我有一个关于 c++ 函数匹配 T
和 const T&
类型参数的问题。
假设我有以下两个功能:
void f(int i) {}
void f(const int &ri) {}
如果我用 const int
类型的参数调用 f
那么这个调用当然是不明确的。但是,为什么使用 int
类型的参数调用 f
也是不明确的?不会是 f
的第一个版本是完全匹配而第二个版本是更差的匹配,因为 int
参数必须转换为 const int
?
const int ci = 0;
int i = 0;
f(ci); // of course ambiguous
f(i); // why also ambiguous?
我知道这种重载没有多大意义,因为 f
的调用几乎总是不明确的,除非参数类型 T 没有可访问的复制构造函数。不过我只是在研究函数匹配的规则。
问候, 凯文
编辑:让我的问题更清楚。如果我有这两个功能:
void f(int *pi) {}
void f(const int *pi) {}
那么下面的调用就没有歧义了:
int i = 0;
f(&i); // not ambiguous, first version f(int*) chosen
尽管 f
的两个版本都可以用 &i
调用,但选择了第一个版本,因为 f
的第二个版本将包含一个转换到 const.
也就是说,第一个版本是“更好的匹配”。但是在两个函数中:
void f(int i) {} and
void f(const int &ri) {}
由于某些原因,这种对 const
的额外转换似乎被忽略了。同样,f
的两个版本都可以使用 int
调用。但是同样,f
的第二个版本需要转换为 const
,这会使它比第一个版本 f(int) 更差。
int i = 1;
// f(int) requires no conversion
// f(const int &) does require a const conversion
// so why are both versions treated as "equally good" matches?
// isnt this analogous to the f(int*) and f(const int*) example?
f(i); // why ambiguous this time?
最佳答案
一个调用涉及“左值到右值的转换”,另一个需要身份转换(对于引用)或“资格调整”(对于指针),根据标准,当涉及到重载决议。
因此,根据不同的转化率,两者都不是更好。
但是,在标准第 13.3.3.2 节中有一条特殊规则,该规则仅适用于被比较的两个候选者通过引用采用参数的情况。
Standard conversion sequence
S1
is a better conversion sequence than standard conversion sequenceS2
if ...S1
andS2
are reference bindings (8.5.3), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized byS2
refers is more cv-qualified than the type to which the reference initialized byS1
refers.
指针也有相同的规则。
因此编译器会更喜欢
f(int*);
f(int&);
结束
f(const int*);
f(const int&);
分别,但没有偏好 f(int)
vs f(const int)
vs f(const int&)
,因为左值- 右值转换和资格调整都被认为是“精确匹配”。
也相关,来自第 13.3.3.1.4 节:
When a parameter of reference type binds directly to an argument expression, the implicit conversion sequence is the identity conversion, unless the argument expression has a type that is a derived class of the parameter type, in which case the implicit conversion sequence is a derived-to-base Conversion.
关于c++ - const T& 和 T 类型参数的函数匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18409239/