#include <iostream>
class Bar{};
void foo(const Bar x){} //l5
void foo(Bar x){} //l6
void foo(Bar const x){} //l7
////pointer functions
void foo(const Bar* x){} //l11
void foo(Bar* x){} //l12
void foo(Bar* const x){} //l13编译器输出:(长话短说的l5,l6,l7冲突;但只有l12,l13冲突)
untitled.cpp:6:6: error: redefinition of ‘void foo(Bar)’
untitled.cpp:5:6: error: ‘void foo(Bar)’ previously defined here
untitled.cpp:7:6: error: redefinition of ‘void foo(Bar)’
untitled.cpp:5:6: error: ‘void foo(Bar)’ previously defined here
untitled.cpp:13:6: error: redefinition of ‘void foo(Bar*)’
untitled.cpp:12:6: error: ‘void foo(Bar*)’ previously defined here怎么回事?
l12和l13之间的冲突,即使l12不包含const关键字。发布于 2013-01-09 18:04:37
“问题”是参数值的const不参与重载!
首先,Bar const和const Bar的含义已经相同,因此它们会自动出现问题。但是作为函数参数,const不适用于重载,因此函数的Bar版本看起来也是一样的。参数表中的const只告诉编译器,您不打算在函数体中修改它。
出于同样的原因,Bar*和Bar* const被同等对待:const应用于参数的值(而不是指向的值),并且不参与重载,因此定义了相同的函数。
另一方面,const Bar*意味着完全不同的东西:指向const对象(Bar类型)的非const指针。由于类型不同,它确实参与重载,并允许该函数是唯一的。
发布于 2013-01-09 17:58:19
基本上,因为C++在调用函数时复制值,所以没有什么可以从调用者的角度区分前三个值。(调用方知道函数不能更改它自己传入的值,因此从调用方的角度来看,每个函数参数在很多方面都是隐式不变的)。
然而,当您谈到指针时,如果将指向常量的指针传递给非常数的指针,则调用方会有不同之处(一个不会更改您的内容,另一个可能会)。这就是为什么l11和l12不冲突的原因。
但是,l12和l13之间存在冲突,因为它们都是指向Bar*的指针(一个是const指针,另一个不是,所以与l5-l7一样,调用方没有区别)。
最后一点可能有点棘手--注意,虽然int const *a与const int *a相同,但它们与int * const a不一样,前两个是指向常量int的指针,另一个是指向int的常量指针(即指针的值在后面不能更改)。
发布于 2013-01-09 17:57:26
前三个创建冲突的原因是编译器无法确定在任何情况下使用哪个函数。当您调用foo(BarObject);时,编译器可以很好地使用它们中的任何一个,不管是否声明为const。
但是,对于以参数作为指针的对象,当调用foo(BarPointer); (如果BarPointer声明为const Bar* BarPointer; )时,编译器将选择]11,因为它确保指向的对象不会在函数中被修改(在按值传递时不会像前三次那样)。如果不是const,则不知道应该调用]12还是]13,因为Bar* const x的意思是,"x不能指向传递为参数的其他任何东西“,这与调用方无关。
略为提及这些声明:
const Bar x // x is an immutable copy of the original parameter.
Bar const x // same as above and gets compiled, but cdecl says it is a syntax error.
const Bar* x // x points to an object that can't be changed.
Bar* const x // x can't point to any other object than the parameter passed.https://stackoverflow.com/questions/14243269
复制相似问题