通过重载运算符[]附加到数组

时间:2017-09-23 08:40:24

标签: c++

我想在C ++中定义一个构造a[] = 1,它允许我追加到自定义数组对象而不是像push_back()这样的东西。

是否可以通过c ++中的某些运算符重载来实现这一点?

我在考虑[]返回重载=的引用。但是operator [](void)无效,但也许有一些技巧?

3 个答案:

答案 0 :(得分:3)

我强烈建议只创建一个push_back方法。它的惯用语和人们现在的作用。任何其他技巧对用户来说都是令人惊讶的。

但是如果你坚持这里有一些技巧可以做:

struct To_back {};
constexpr To_back to_back;

struct X
{
    auto operator[](To_back) -> Back_inserter_proxy
    {
        return Back_inserter_proxy{*this};
    }
};
X x;

x[to_back] = 24;

或:

struct X
{
    auto operator%=(int elem)
    {
        // push back here
    }
    // or
    auto operator<<(int elem)
    {
        // push back here
    }
};
X x
x %= 24;
// or
x << 24;

但是我重申:我强烈建议不要使用这些技巧,特别是因为有一种简单的惯用方法:push_back

答案 1 :(得分:2)

  

然而operator [](void)无效,但也许有一些技巧?

没有任何问题或技巧可以解决这个问题。

  

是否可以通过c ++中的某些运算符重载来实现这一点?

您可以获得的最接近的是索引运算符重载,如果索引当前超出范围,它将自动调整实习std::vector的大小:

template<typename T>
class AutoArray {
    std::vector<T> v;
public:
    T& operator[](size_t index) {
        if(index >= v.size()) {
            v.resize(index + 1);
        }
        return v[index];
    }
};

例如,当效率不高时虽然在任意索引循环中使用。

答案 2 :(得分:0)

只是为了好玩。从理论上讲,你可以这样做:

#include <vector>
#include <type_traits>
#include <iostream>

template <class U>
struct Arr {
    template <class T, std::enable_if_t<std::is_integral_v<T>>* = nullptr>
    U &operator[](T i) { return v[i]; }
    U &operator[](decltype(nullptr)){
        v.push_back({});
        return v[v.size() - 1];
    }
private:
std::vector<U> v;
};

int main() {
    Arr<int> a;
    a[{}] = 100;
    a[{}] = 2;
    std::cout << a[0] << std::endl;
    std::cout << a[1] << std::endl;
}

输出:

100
2

[live demo]

但不要这样做......仍然认为push_back更简单。