仅为特定 class 的成员重载 operator[]

Overloading operator[] only for members of a specific class

编辑:MyClass 已重命名为 ReverseStringAccess 以消除歧义。

我有一个 class 封装了一个 vector<string>。 class 有一个重载的 operator[] 可用于读取和修改向量的内容。这是它的外观(最低限度):

class ReverseStringAccess {
    public:
        ReverseStringAccess() {}
        ReverseStringAccess(vector<string> _arr) arr(_arr) {}
        string& operator[](int index) {
            return arr[index];
        }
    private:
        vector<string> arr;
};

现在我需要能够在不直接访问向量的情况下修改向量中每个字符串的内容(即某种 operator[][] 仅适用于作为此 [=43= 成员的向量]).问题是使用 ReverseStringAccess[][] 将导致 operator[] 在字符串上的默认行为。例如,这条语句:

ReverseStringAccess[i][j]

会给出向量中第 ith 个字符串的第 jth 个字符。但我希望它(例如)获取向量中 ith 字符串的 (length - j - 1)th 字符,其中 length 是第 ith 个字符串的长度。

这可能吗?如果是,如何?

如果您希望 my_object[i][k] 不调用 std::string::operator[],则不要 return 来自 MyClass::operator[]std::string&,而是实现所需的代理[]:

class MyClass {
    public:
        MyClass() {}
        MyClass(vector<string> _arr) arr(_arr) {}

        struct MyProxy {
             std::string& str;
             char& operator[](size_t index) { /.../ }
             const char& operator[](size_t index) const { /.../ }
        };

        MyProxy operator[](int index) {
            return {arr[index]};
        }
    private:
        vector<string> arr;
};

问题是如何通过[][]vector<string>的成员实现反向索引。

这可以通过包装器 class 实现 std::string:

template<typename T>
class reverse_access {
    T& ref;
public:
     // create wrapper given reference to T
     reverse_access(T& ref_)
         : ref(ref_)
     {}

     // reverse access operator []
     auto operator[](size_t i) -> decltype(ref[0])
     { return ref[ ref.size() - 1 - i]; }
     auto operator[](size_t i) const -> decltype(ref[0])
     { return ref[ ref.size() - 1 - i]; }

      // allow implicit conversion to std::string reference if needed
     operator T&() { return ref; }
     operator const T&() const { return ref; }
};

// inside MyClass:
        reverse_access<string> operator[](int index) {
            return reverse_access<string>(arr[index]);
        }
        reverse_access<const string> operator[](int index) const {
            return reverse_access<const string>(arr[index]);
        }

并在 MyClass 的 operator[] 中使用 return reverse_access<std::string>(arr[index]);。 添加的转换运算符允许隐式转换为对原始类型的引用。

另一种选择是使用可以接受 2 个参数的不同运算符:myclass(vec_index,str_index):

        string::reference operator()(size_t vec_index, size_t str_index)
        {
            return arr[vec_index][ arr[vec_index].size() - str_index ];
        }
        string::const_reference operator()(size_t vec_index, size_t str_index) const
        {
            return arr[vec_index][ arr[vec_index].size() - str_index ];
        }

第三种解决方案是在构造 ReverseStringAccess 时反转所有字符串:

ReverseStringAccess(vector<string> _arr) arr(_arr) 
{
   for (auto& str : arr)
       std::reverse(str.begin(), str.end());
}