C ++中的Overload []运算符支持自定义集函数

问题描述 投票:1回答:2

我有一个模拟数组的C ++类,为了操作它的成员,我实现了两个函数:set(size_t index, size_t value)get(size_t index)。我想重载[]运算符以具有以下功能:

MyCustomArray[index] = value //->set(size_t index, size_t value)

value = MyCustomArray[index] //->get(size_t index)

get可以通过重载轻松实现,但我不知道如何实现set,因为我事先需要参数value

我的类是固定字数组的实现(数组中的元素最多有P位,其中P是参数,它可以小于常规机器字)。为了支持此功能,setget在常规C / C ++数组中操作值的一系列位。

在这种情况下是否可能超载?

提前致谢!

c++ operator-overloading
2个回答
2
投票

这就像std :: vector :: operator []正在做的那样 - 使用代理对象。

class MyCustomArray
{
public:
    using value_type = unsigned;
    class Proxy
    {
    public:
        friend class MyCustomArray;
        operator value_type() const 
        {
            return m_customArray.get(m_index);
        }
        Proxy & operator=(value_type value)
        {
            m_customArray.set(m_index, value);
            return *this;
        }
    private:
        Proxy(MyCustomArray & customArray, size_t index) 
            : m_customArray(customArray), m_index(index) {}
        MyCustomArray & m_customArray;
        size_t m_index;
    };
    value_type operator[](size_t index) const
    {
        return get(index);
    }
    Proxy operator[](size_t index) 
    {
        return Proxy(*this, index);
    }
    value_type get(size_t index) const;
    void set(size_t index, value_type value);
private:
    /// The data goes here
};

然后

void work(MyCustomArray & arr)
{
    // Return a Proxy object, and call operator= over it.
    arr[3] = 5;

    // arr_2 is of type MyCustomArray::Proxy
    auto arr_2 = arr[2];
    arr_2 = 1; // modifies arr[2]
    unsigned x = arr_2; // gets 1 from arr[2] 

    // This works, due to auto conversion to value_type:
    std::cout << arr_2 << '\n';
}

1
投票

正如评论中所提到的,这可以通过让operator[]返回一个代理对象来实现,这就是std::vector<bool>执行其魔力的方式。

在你的情况下,它会看起来像这样:

struct MyCustomArray;

struct ArrayMemberRef {
  MyCustomArray* target_;
  std::size_t index_;

  ArrayMemberRef& operator=(std::size_t value);
  operator std::size_t();
};

struct MyCustomArray {
  ArrayMemberRef operator[](std::size_t index) {
    return ArrayMemberRef{this, index}; 
  }

  void set(std::size_t index, std::size_t value);
  int get(std::size_t index);
};

ArrayMemberRef& ArrayMemberRef::operator=(std::size_t value) {
  target_->set(index_, value);
  return *this;
}

ArrayMemberRef::operator std::size_t() {
  return target_->get(index_);
}
© www.soinside.com 2019 - 2024. All rights reserved.