在c ++中,为什么编译器在const工作时也会选择非const函数?

Cal*_*itt 18 c++ compiler-construction const

例如,假设我有一个类:

class Foo
{
public:
    std::string& Name()
    {
        m_maybe_modified = true;
        return m_name;
    }

    const std::string& Name() const
    {
        return m_name;
    }
protected:
    std::string m_name;
    bool m_maybe_modified;
};
Run Code Online (Sandbox Code Playgroud)

在代码中的其他地方,我有这样的事情:

Foo *a;
// Do stuff...
std::string name = a->Name(); // <-- chooses the non-const version
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么编译器在这种情况下会选择非const版本?

这是一个有点人为的例子,但我们试图解决的实际问题是如果对象已经改变则定期自动保存,并且指针必须是非const的,因为它可能在某些时候被更改.

Lev*_*Lev 18

因为a不是const指针.因此,非const函数是更接近的匹配.以下是调用const函数的方法:

const Foo* b = a;
std::string name = b->Name();
Run Code Online (Sandbox Code Playgroud)

如果你同时拥有const和非const重载,并且想要在非const对象上调用const,那么这可能表明设计不好.


小智 16

脑海中浮现出两个答案:

  1. 非const版本更接近匹配.

  2. 如果它呼吁非const情况下,const的过载,那么在什么情况下会是有史以来调用非const超载?

您可以通过转换a为a 来使用其他重载const Foo *.

编辑:来自C++注释

早些时候,在2.5.11节中介绍了函数重载的概念.它注意到成员函数可能仅仅通过其const属性重载.在这些情况下,编译器将使用最接近对象的const限定的成员函数:


Mar*_*som 6

编译器不会考虑如何在其确定中使用返回值; 这不是规则的一部分.它不知道你是否正在做

std::string name = b->Name();
Run Code Online (Sandbox Code Playgroud)

要么

b->Name() = "me";
Run Code Online (Sandbox Code Playgroud)

它必须选择适用于这两种情况的版本.