vso*_*tco 9 c++ pass-by-reference
我有以下代码:
#include <iostream>
template <typename T>
void f(T& x)
{
std::cout << "f(T& )" << std::endl;
}
template <typename T>
void f(const T& x)
{
std::cout << "f(const T& )" << std::endl;
}
int main()
{
int a = 0;
const float b = 1.1;
f(a); // call f(T&)
f(b); // call f(const T&)
}
Run Code Online (Sandbox Code Playgroud)
输出是:
f(T& )
f(const T& )
Run Code Online (Sandbox Code Playgroud)
我的问题是:编译器如何知道要调用哪个函数?如果我从函数定义中删除引用,那么我会得到一个"模糊调用"类型的错误,即error: redefinition of 'f'.对我来说,它看起来f(T&)可以同样适用于两个调用,为什么const明确要求版本f(b)?
鉴于两个相互竞争的重载,标准要求编译器选择具有"最佳匹配"的重载.(如果没有唯一的最佳过载,或者如果无法访问唯一的最佳过载,则程序格式不正确.)
在这种情况下,规则由§13.3.3.2[over.ics.rank]/p3提供:
标准转换序列S1是比标准转换序列S2更好的转换序列,如果:
[...]
S1和S2是引用绑定(8.5.3),引用引用的类型除了顶级cv限定符之外是相同的类型,并且S2引用的引用所引用的类型比cv更合格.由S1初始化的引用所引用的类型.
这是标准中给出的示例:
int f(const int &);
int f(int &);
int g(const int &);
int g(int);
int i;
int j = f(i); // calls f(int &)
int k = g(i); // ambiguous
Run Code Online (Sandbox Code Playgroud)
在你的情况下,const T&更符合cv T&标准,因此通过标准,f(T&)更适合f(const T&)并且通过重载分辨率选择.
f(T&)vsf(T const&)
这两个函数是不同的,因为第一个签名表明通过引用传递的任何变量都可以被函数修改.因此const float不能传递给第一个函数,第二个函数是编译器唯一可行的选择.nonconst变量可以传递给两者,因此编译器必须选择更合适的变量(如果有的话).标准说,为了调用第二个函数,编译器必须const向任何nonconst变量添加一个,而对于第一个函数,这不是必需的.添加const是一种隐式转换,它是一种"更糟糕"的转换(读取更多转换步骤)而不是添加任何内容.因此,标准要求编译器在传递非对象变量时选择第一个函数.
如果你想知道:文字和临时文件不能绑定到nonconst引用,那么f(4),f("meow")并且f(someFunc())都会调用第二个函数.
f(T)与f(const T)
它们看起来不同,但不是在重载分辨率或功能签名方面.它们都是按值调用,或者是编译器:将参数的副本传递给函数.唯一的区别在于函数定义,您需要变量在函数体中保持不变.任何函数声明都不会影响函数定义签名中的变量定义:
void f(int); //a declaration
void f(int i); //redeclaration of the same function
void f(int const); //still the same function redeclared
void f(int const i2); //yes... a redeclaration
void f(int const i) { //at last a function definition and the copy of the argument used in the function body is required to be const
//...
}
void f(int i) { //there is only one f, so this is a redefinition!
//...
}
Run Code Online (Sandbox Code Playgroud)
这不是"ambuguos调用类型错误",因为编译器只有一个函数而且没有歧义.错误只是你确实两次确定相同的功能.出于这个原因,在许多样式指南中,首选函数声明没有顶级const,编译器通常会忽略它们,而不会在错误或警告消息中提及它们.