为什么编译器可以通过引用传递和值传递来重载函数
Why the compiler can overload functions with passing by reference and passing by value
我认为在重载过程中,编译器会检查形式参数是否属于同一类型。例如:
void a(int x)
void a(double x)
可以重载,因为两个"x"具有不同的类型。
但是,以下两种类型不同吗?
void f(int y)
void f(int& y)
我知道一个是PBV,另一个是PBSR。但是第二个y的类型也是"int",对吧?为什么它编译成功?
p.S。我注意到,尽管它进行了编译,但它并没有运行,报告了运行时的模糊错误。
广义函数可以在以下基础上重载:
- 参数数
- 参数的类型
- 自变量的顺序
编译该示例是因为它满足第二个条件int
和int &
是不同的数据类型。
考虑以下示例:
void foo(int i);
void foo(int& i);
void foo(int i){}
void foo(int& i){}
int main()
{
return 0;
}
上面的代码之所以编译,是因为它是有效的代码。根据传递给函数的函数参数,编译器可能检测不到函数调用的最佳匹配。因此,函数本身可以共存,但它们在某些方面的使用可能会给编译器带来歧义。
例如:在以下代码中,文字不能绑定到非常量引用,因此函数调用的唯一候选版本是非引用版本,这应该可以编译并正常工作:
void foo(int i);
void foo(int& i);
void foo(int i){}
void foo(int& i){}
int main()
{
foo(20);
return 0;
}
但是,
void foo(int i);
void foo(int& i);
void foo(int i){}
void foo(int& i){}
int main()
{
int i = 10;
foo(i);
return 0;
}
由于编译器无法检测到两个函数调用之间的最佳匹配,因此上述情况将导致编译器产生歧义。
首先,总是在编译时报告模糊性。
其次,你的例子是否编译取决于你如何使用这个函数
void f(int y)
{
}
void f(int& y)
{
}
int main ()
{
int a = 10;
f (a); // ERROR: ambiguous call
f (10); // OK
}
在第一种情况下会出现错误,因为a
可以作为副本和引用传递。在第二种情况下,将不会出现错误,因为int
文字无法通过非常量引用传递
这取决于情况。如果你不从代码中调用这些函数,编译器可能会对它们进行优化。如果没有,您可以使用文本查看器打开.obj文件并搜索函数名称(给它一个比f
更唯一的名称,例如floop
:-),您将使用基本函数名称看到两个损坏的名称。
但如果你真的尝试使用它们,那么你会注意到不同。如果你打电话给
f(5);
编译器只能使用f(int y)
版本,因为不可能通过引用传递常量。但如果你做
int b = 10;
f(b);
然后编译器将发出一个友好错误,因为两个f
形式都可以用这种方式调用。
让我们调用f(x),其中x是int。
$13.3.3.1.4-"当引用类型的参数直接绑定时(8.5.3)对于自变量表达式,隐式转换序列为标识转换,除非参数表达式具有类型是参数类型的派生类,在这种情况下隐式转换序列是一种派生到基的转换">
因此f(int&)是一个精确匹配,f(int)也是,因为两者都是身份转换。因此,模糊
现在让我们接电话"f(2)">
这很好,因为'f(int&)'根本不匹配,因为右值不绑定到非常值。因此,无歧义
因此,该标准允许"f(T)"answers"f(T&)"形成一个重载集。
- 为什么可以将左值传递给"std::async",即使它引用了右值
- 使用赋值运算符重载从类中返回jobject
- 赋值运算符重载和自赋值
- 当值传递给C++中的运算符重载函数时会发生什么
- 有什么理由用右值引用重载运算符吗?
- std::forward() 的右值引用重载的目的是什么?
- std::move into static_pointer_cast:为什么static_pointer_cast没有右值引用重载?
- 如何将非可变参数值传递给 fmt::format?
- 将 qml 项目值传递给 cpp 后如何与它们进行交互?
- NDK:将文本字段值传递给 c++ 字符串
- C++ 指针赋值运算符重载(不仅是对象赋值,还有指针赋值)
- 赋值运算符重载在通过指针访问时不调用
- "return *this"赋值运算符重载
- 赋值运算符重载 c++ 的返回值
- 在对类对象的赋值进行链接时获取垃圾值,使用按值返回类对象的赋值运算符重载
- 如何将值传递给 lambda 函数
- 如何在C++中将std::string值传递给RegSetValueEx()
- 如何将 c ++ 变量的值传递给 hadoop HDFS 的 bash 系统命令?
- C++ 通过参数将值传递给 char 数组
- 在解析分配给默认参数值的重载函数时,要考虑哪组函数