STL是充满了这样的定义:const和非const函数的重载是如何工作的?
iterator begin();
const_iterator begin() const;
由于返回值不参与重载决议,唯一不同的是这里的功能是const
。这是重载机制的一部分吗?什么是编译器的解决像线算法:
vector<int>::const_iterator it = myvector.begin();
STL是充满了这样的定义:const和非const函数的重载是如何工作的?
iterator begin();
const_iterator begin() const;
由于返回值不参与重载决议,唯一不同的是这里的功能是const
。这是重载机制的一部分吗?什么是编译器的解决像线算法:
vector<int>::const_iterator it = myvector.begin();
在你给的例子:
vector<int>::const_iterator it = myvector.begin();
如果myvector
不为const begin()
非const版本将被调用,你将依靠从迭代器到const_iterator的隐式转换。
是的,const
修改影响超载。如果myvector
是const
在这一点上const
版本将被称为:
void stuff(const vector<int>& myvector)
{
vector<int>::const_iterator it = myvector.begin(); //const version will be called
}
vector<int> myvector;
vector<int>::const_iterator it = myvector.begin(); //non-const version will be called
编译器的“算法”是这样的: 类X的每个成员函数都有一个类型为X的隐式参数(我知道,大多数人认为它是X *,但是标准状态,为了解决超载问题,我们假定它是一个参考)。对于const函数,参数的类型是const X &。因此,如果一个成员函数被称为两个版本,const和non-const都是可行的候选者,那么最好的匹配就像在其他重载解析的情况下一样。没有神奇:)
谢谢,这是有用的,但是我的问题是(错误的)假设const变量被调用,因为它被分配的变量的类型。 @awoodland解释了这个 – davka 2011-02-24 11:18:12
为什么引用而不是指针和那个只能用于重载的解析,有什么非明显的原因呢? – 2018-01-30 05:07:58
从C++标准(§13.3.1候选功能和参数列表):
For non-static member functions, the type of the implicit object parameter is “reference to cv X” where X is the class of which the function is a member and cv is the cv-qualification on the member function declaration. [Example: for a const member function of class X, the extra parameter is assumed to have type “reference to const X”. ]
所以,你的情况,如果myvector
对象是const
编译器会挑begin
版本,具有reference to const vector
类型的隐式对象参数,它是常量版本begin
。
值得一提的是,C++ 允许const的方法/函数重载(例如FOO()const的),但不是常量参数超载(例如巴(INT A)和bar(const int的A))。
编译器确定对象变量是const或在编译时间
然后它选择相应的过载,以及任何返回类型它有。
class C {
public:
int f() { return 1; }
float f() const { return 1.5; }
};
// Non const.
C c;
assert(c.f() == 1);
// Convert variable const at compile time.
assert(const_cast<const C&>(c).f() == 1.5);
// Same as above but with an explicit reference.
const C& d = c;
assert(d.f() == 1.5);
// Analogous but with a new const object from the start.
const C e;
assert(d.f() == 1.5);
哦,这解决了难题...所以,有一个转换涉及。谢谢! – davka 2011-02-24 11:11:50