为什么 const 方法不能返回非常量引用?

2022-01-24 00:00:00 reference constants c++ c++11 const-cast

为什么下面的方法 getRanks() 编译不出来,我该如何优雅地修复它?

Why won't the method getRanks() below compile, and how can I fix it gracefully?

我想要做的就是定义一个返回成员引用的成员访问器方法.引用不是 const 因为我以后可能会修改它所引用的内容.但是由于成员方法不修改对象,所以我将它声明为const.编译器(clang,std=c++11)然后坚持认为存在删除限定符"的引用绑定".但我不会放弃预选赛,是吗?如果我是,为什么:

All I want do is define a member accessor method that returns a reference to a member. The reference is not const since I might well modify what it refers to later. But since the member method does not modify the object, I declare it const. The compiler (clang, std=c++11) then insists that there is a "binding of reference" that "drops qualifiers". But I'm NOT dropping qualifiers, am I? And if I am, why:

struct teststruct{
  vector<int> ranks;
  vector<int>& getRanks()const{
    return ranks;
  }
};

现在,如果我更改 return 语句以丢弃 const,则代码编译:

Now, the code compiles if I change the return statement to cast away the const:

return const_cast<vector<int>&>(ranks);

但是ranks"首先不应该是 const,我不明白为什么我需要 const_cast const .我什至不知道这样做是否安全.

But "ranks" should not be const in the first place, I don't see why I need to const_cast the const away. I don't even know if it's safe to do this.

不管怎样,有没有更清洁的方法可以写这个方法?有人可以解释为什么这种简单的常识方法会失败吗?我确实想声明 getRanks() 方法const",以便我可以从其他 const 方法调用它.

Anyway, is there a cleaner to write this method? Can someone explain why such a simple common-sense method fails? I do want to declare the getRanks() method "const" so that I can call it from other const methods.

推荐答案

const 成员函数背后的想法是您应该能够在 const 对象上调用它们.const 函数不能修改对象.

The idea behind the const member function is you should be able to call them on const objects. const functions can't modify the object.

假设你有一堂课

class A
{
   int data;
   void foo() const
   {
   }
};

关于对象和函数调用:

A const a;
a.foo();

A::foo 内部,this->data 被视为其类型为 int const,而不是 int.因此,您无法在 A:foo() 中修改 this->data.

Inside A::foo, this->data is treated as if its type is int const, not int. Hence, you are not able to modify this->data in A:foo().

以您的示例为例, getRanks()this->ranks 的类型将被视为 const vector<int> 而不是 vector.由于不允许将 const vector<int> 自动转换为 vector<int>&,因此当您将函数定义为时,编译器会报错:

Coming to your example, the type of this->ranks in getRanks() is to be considered as const vector<int> and not vector<int>. Since, auto conversion of const vector<int> to vector<int>& is not allowed, the compiler complains when you define the function as:

vector<int>& getRanks()const{
    return ranks;
  }

如果你将函数定义为:

const vector<int>& getRanks()const{
    return ranks;
  }

因为 const vector 可以自动转换为 const vector&.

since const vector<int> can be auto converted to const vector<int>&.

相关文章