const和非const函数的重载如何工作?

时间:2011-02-24 10:46:54

标签: c++ const overloading

stl充满了这样的定义:

iterator begin ();
const_iterator begin () const;

由于返回值不参与重载分辨率,因此这里唯一的区别是函数为const。这是超载机制的一部分吗?什么是解析一行这样的编译器算法:

vector<int>::const_iterator it = myvector.begin();

6 个答案:

答案 0 :(得分:10)

在您给出的示例中:

vector<int>::const_iterator it = myvector.begin();

如果myvector不是const,则将调用begin()的非const版本,并且您将依赖于从迭代器到const_iterator的隐式转换。

答案 1 :(得分:10)

编译器的“算法”是这样的: 类X的每个成员函数都有一个类型为X&amp;的隐式参数。 (我知道,大多数人认为它是X *,但标准规定,为了超载分辨率,我们假设它是一个参考)。对于const函数,参数的类型是const X&amp ;.因此,如果成员函数被称为const和非const两个版本,算法都是可行的候选者,并且选择最佳匹配就像在其他重载决策情况下一样。没有魔法:)

答案 2 :(得分:4)

是的,const修饰符会影响重载。如果此时myvectorconst,则会调用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

答案 3 :(得分:3)

从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类型的隐式对象参数,它是{的{版本} {1}}。

答案 4 :(得分:2)

值得一提的是c ++ 允许const方法/函数重载(例如foo()const),但不是const参数重载(例如bar(int a)和bar) (const int a))。

答案 5 :(得分:1)

编译器在编译时确定对象变量是否为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);