C++ 常量和非常量函数的重载是如何工作的?

C++ 常量和非常量函数的重载是如何工作的?,c++,function,stl,constants,overloading,C++,Function,Stl,Constants,Overloading,STL中充满了这样的定义: iterator begin (); const_iterator begin () const; 由于返回值不参与重载解析,这里唯一的区别是函数为const。这是过载机制的一部分吗?编译器解析以下行的算法是什么: vector<int>::const_iterator it = myvector.begin(); vector::const_迭代器it=myvector.begin(); 是的,const修饰符会影响重载。如果此时myvector为c

STL
中充满了这样的定义:

iterator begin ();
const_iterator begin () const;
由于返回值不参与重载解析,这里唯一的区别是函数为
const
。这是过载机制的一部分吗?编译器解析以下行的算法是什么:

vector<int>::const_iterator it = myvector.begin();
vector::const_迭代器it=myvector.begin();

是的,
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
void stuff(const vector和myvector)
{
vector::const_迭代器it=myvector.begin();//将调用const version
}
向量myvector;
vector::const_迭代器it=myvector.begin()//将调用非常量版本

是的,
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
void stuff(const vector和myvector)
{
vector::const_迭代器it=myvector.begin();//将调用const version
}
向量myvector;
vector::const_迭代器it=myvector.begin()//将调用非常量版本

在您给出的示例中:

vector<int>::const_iterator it = myvector.begin();
vector::const_迭代器it=myvector.begin();

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

在您给出的示例中:

vector<int>::const_iterator it = myvector.begin();
vector::const_迭代器it=myvector.begin();
如果
myvector
不是常量,则将调用
begin()
的非常量版本,您将依赖于从迭代器到常量迭代器的隐式转换。

编译器的“算法”如下所示: 类X的每个成员函数都有一个类型为X的隐式参数&(我知道,大多数人认为它是X*,但标准规定,为了重载解析的目的,我们假设它是一个引用)。对于常量函数,参数的类型为常量X&。因此,如果一个成员函数被调用,那么两个版本(const和non-const)都是可行的候选者,并且选择最佳匹配,就像在重载解析的其他情况下一样。没有魔法:)

编译器的“算法”如下: 类X的每个成员函数都有一个类型为X的隐式参数&(我知道,大多数人认为它是X*,但标准规定,为了重载解析的目的,我们假设它是一个引用)。对于常量函数,参数的类型为常量X&。因此,如果一个成员函数被调用,那么两个版本(const和non-const)都是可行的候选者,并且选择最佳匹配,就像在重载解析的其他情况下一样。没有魔法:

< P>从C++标准(第133.1候选函数和参数列表):

对于非静态成员函数,隐式对象参数的类型为“引用cv X”,其中X是函数所属的类,cv是成员函数声明上的cv限定。[示例:对于类X的常量成员函数,假定额外参数的类型为“reference to const X”。

<> P> >在您的情况下,如果<代码> MyVector 对象是“代码> const 编译器将选择版本<代码>开始/<代码>,它具有“类型代码<隐式对象参数>引用const vector < /代码>,这是const版本的<代码>开始< /代码> .< /p> 从C++标准(第133.1候选函数和参数列表):

对于非静态成员函数,隐式对象参数的类型为“引用cv X”,其中X是函数所属的类,cv是成员函数声明上的cv限定。[示例:对于类X的常量成员函数,假定额外参数的类型为“reference to const X”。


所以,在你的情况下,如果<代码> MyVector 对象是代码> const 编译器将选择版本<>代码>开始/代码>,它具有类型为“代码>的隐式对象参数>引用const vector < /COD> >这是const版本的代码>开始< /代码> .< /p> < p>值得注意的是C++ +<强>允许const方法/函数重载>(例如,For)(const),但是<>强> >非const参数重载(例如Bar(int a)和bar(const int a)).< /p> 值得一提的是C++ > <强>允许const方法/函数重载(例如,FoE()),但是<强>不const参数重载(例如Bar(int a)和bar(const int a)).

编译器在编译时确定对象变量是否为常量

然后它选择相应的重载,以及它具有的任何返回类型

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);
C类{
公众:
int f(){return 1;}
float f()常量{return 1.5;}
};
//非常量。
C C;
断言(c.f()==1);
//在编译时转换变量const。
断言(const_cast(c).f()==1.5);
//同上,但有明确的参考。
常数C&d=C;
断言(d.f()==1.5);
//类似,但从一开始就有一个新的const对象。
常数C e;
断言(d.f()==1.5);

编译器在编译时确定对象变量是否为常量

然后它选择相应的重载,以及它具有的任何返回类型

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);
C类{
公众:
int f(){return 1;}
float f()常量{return 1.5;}
};
//非常量。
C C;
断言(c.f()==1);
//在编译时转换变量const。
断言(const_cast(c).f()==1.5);
//同上,但有明确的参考。
常数C&d=C;
断言(d.f()==1.5);
//类似,但从一开始就有一个新的const对象。
常数C e;
断言(d.f()==1.5);

谢谢,这很有用,但是我的问题是(错误的)假设调用const变量是因为它被分配给的变量的类型@阿伍德兰德解释了这一点