C++ 为什么下标运算符C++;你经常成对来吗?

C++ 为什么下标运算符C++;你经常成对来吗?,c++,operator-overloading,constants,operator-keyword,C++,Operator Overloading,Constants,Operator Keyword,正在定义模板容器矩阵,以避免棘手的新建删除代码。教程说下标操作符经常成对出现?为什么会这样 T& operator() (unsigned i, unsigned j); T const& operator() (unsigned i, unsigned j) const; 为什么会这样 T& operator() (unsigned i, unsigned j); T const& operator() (unsigned i, u

正在定义模板容器
矩阵
,以避免棘手的
新建
删除
代码。教程说下标操作符经常成对出现?为什么会这样

T&       operator() (unsigned i, unsigned j); 
T const& operator() (unsigned i, unsigned j) const;
为什么会这样

T&       operator() (unsigned i, unsigned j); 
T const& operator() (unsigned i, unsigned j) const;
这也称为:常量重载

常见问题解答提供了线索。你还有其他意见吗


特别是,如果
mutate()
遵守某些规则,以便仅在常量对象上安全使用?

T&
对象上调用下标运算符,则调用第一个非常量运算符。然后,允许进行检查和变异操作


调用
T常量&
对象上的下标运算符,调用第二个常量运算符。然后,允许检查,但不允许变异

这里就是一个例子

void f(MyFredList const& a)  ← the MyFredList is const
{
  // Okay to call methods that DON'T change the Fred at a[3]:
  Fred x = a[3];
  a[3].inspect();

  // Error (fortunately!) if you try to change the Fred at a[3]:
  Fred y;
  a[3] = y;       ← Fortunately(!) the compiler catches this error at compile-time
  a[3].mutate();  ← Fortunately(!) the compiler catches this error at compile-time
}

<> P>到C++ FAQ,更多。

简单地说,因为赋值有两个方面:左边和右边。< /P> 非常量版本:

T&operator()(无符号i,无符号j)主要用于分配的左侧(即用作分配的目标)

常量版本:
T const&operator()(无符号i,无符号j)const仅用于分配的右侧

但请注意措辞上的差异:常量版本只能在赋值的右侧使用,而非常量版本可以在任意一侧使用。但是,如果您有一个
const
-qualified对象,那么您只能调用const-qualified成员函数,因此在这种情况下根本不能使用它。这正是您(至少在正常情况下)想要的——它阻止修改您说过不应该修改的对象(通过常量限定它)

mutate
而言,它通常只用于逻辑状态和按位状态之间存在差异的对象。一个常见的例子是一个类,它懒散地进行一些(通常是昂贵的)计算。为避免重新计算该值,它会在计算后保存该值:

class numbers { 
    std::vector<double> values;
    mutable double expensive_value;
    bool valid;
public:
    numbers() : valid(false) {}

    double expensive_computation() const { 
        if (valid) return expensive_value;
        // compute expensive_value here, and set `valid` to true
    }
};
在某些情况下,我们可能还需要一个中间级别的有效性——我们可能能够更快速地重新计算
昂贵的\u值
,方法是(例如)准确地知道哪些数字已添加到
,而不仅仅是用布尔值来表示它当前是否有效


我可能应该补充一下,C++11在
const
mutable
两方面都增加了一些新的需求。长话短说,在大多数情况下,您需要确保
常量
和/或
可变
的任何内容也是线程安全的。你可能想看看这个。然而,我确实觉得有必要补充一点,我认为他关于
可变的结论可能有点夸张(但我宁愿你自己看,自己决定,也不要相信我的话)。

可能的重复公平地说,这里只提到了
操作符[]
(类似数组的类)。非常感谢!“但是,如果您有一个const限定对象,那么您只能调用const限定成员函数,因此在这种情况下它根本不能使用。”,您的意思是非const版本根本不能使用?“
mutate
”…-您展示了一个可以对非const成员调用const的情况(使用
mutable
),并用一个惰性计算示例说明,逻辑常量成员可以看到其值的变化,对吗?我这样问是因为举例来说,解释是非常清楚和完整的,但我没有理解为什么会有这样的解释。