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

Appending to an array via overloading the operator[]

本文关键字:追加 数组 重载 运算符      更新时间:2023-10-16

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

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

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

我的强烈建议是创建一个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.

但是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];
}
};

例如,当在任意索引循环中使用时,这不会非常有效。

只是为了好玩。从理论上讲,您可以执行以下操作:

#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

[现场演示]

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