【问题标题】:How can std::string operator[] return a reference rather than the character?std::string operator[] 如何返回引用而不是字符?
【发布时间】:2015-03-21 18:04:56
【问题描述】:

我正在阅读 Scott Meyers 的《Effective C++》一书,并在阅读第 3 条 - 尽可能使用 const 时发现这个示例非常具有误导性。

我的问题是 - 数组访问如何返回感兴趣索引处的引用而不是该索引处的项目。

还附上我执行的程序以供参考,以确认正在发生这种情况

#include <iostream>
#include <string>

using namespace std;

class TextBlock
{
    public:
        explicit TextBlock(const std::string str) : text(str) {}
        const char& operator[](std::size_t position) const { return text[position]; }
        char& operator[](std::size_t position) { return text[position]; }

        std::string get_text() { return text; }

    private:
        std::string text;
};

int main()
{
    TextBlock tb("Hello");
    cout << "Before calling operator overloading " << tb.get_text() << "\n";
    tb[0] = 'I';
    cout << "After calling operator overloading " << tb.get_text() << "\n";
    return 0;
}

我得到了相应的输出

Before calling operator overloading Hello
After calling operator overloading Iello

观察到的行为是否特定于运算符重载?

【问题讨论】:

  • std::string 的重载运算符 [] 返回一个引用,您只是从班级的重载 [] 转发它。所以你得到一个作为操作符结果的引用,并且可以使用这个引用来修改字符串内容。你的意图是什么?
  • @AlexShesterov 我想知道如何通过索引值访问字符串会返回对感兴趣位置的引用,而不是有问题的项目。你的回答帮助了我。这是一个需要投反对票的基本疑问吗?
  • 我没有否决您的问题。我会给你一个赞成票来补偿-1
  • why operator[] 通常返回引用的原因是数组索引表达式产生左值。也就是说,设int arr[10] = {};,那么表达式arr[2] 是一个左值:arr[2] = 42; 是良构的。 std::string 的重载的operator[] 在这方面模仿了内置的数组索引

标签: c++ operator-overloading


【解决方案1】:

我的问题是 - 数组访问如何返回感兴趣索引处的引用而不是该索引处的项目。

不是数组访问。当您执行text[position] 时,您正在调用std::string 的以下重载。

char& std::string::operator [] ( std::size_t index ) ;

返回一个引用到字符串指定位置的一个字符,它实际上是一个字符的容器。这类似于其他容器的工作方式,例如std::mapstd::vector。通过为类重载索引运算符,可以实现此行为。否则它将是未定义的,因为索引只能在实现了重载的指针/数组或类上进行。

话虽如此,应该记住数组索引实际上是指针解引用,这意味着它可以以相同的方式绑定到引用并导致相同的结果,如下所示(试一试)。这是因为carray[i] 等同于*(carray + i),这是一种告诉编译器可以隐式地将指针转换为引用的方法。

char& operator [] ( std::size_t i ) { return carray[i]; }
...
char carray[10];

这样实现索引运算符是有充分理由的。它可以有效地让您像对待char[] 一样对待std::string;您可以为任何给定的索引分配一个值,也可以访问任何给定的索引来获取一个值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    相关资源
    最近更新 更多