【发布时间】:2021-01-13 21:06:39
【问题描述】:
假设我有一个自定义容器MyList,如下所示。
template<class T>
class MyList
{
public:
const T& get (size_t index) const
{
Block& block = getBlock (index);
return block.get (index - block.startIndex);
}
void set (size_t index, const T& value)
{
Block& block = getBlock (index);
block.dirty = true;
block.set (index - block.startIndex, value);
}
// ...
};
块基本上是从磁盘加载的缓存数据块(可以有 2-3 个这样的 LRU 块)。如果一个块是脏的,当它不是内存时,它的数据将被写入磁盘。
我的问题如下。
-
重载 operator[] 无法使用正确的 operator[]。我重载了以下两个:
T& operator[](size_t index) { Block& block = getBlock (index); block.dirty = true; return block.get (index - block.startIndex); } const T& operator[](size_t index) const { return get (index); }
但是,如果MyList 不是const 版本,g++ 会调用第一个。也就是说,对于如下代码:
MyList<int> list;
// ...
int myValue = list[0];
调用的 operator[] 总是第一个设置脏位的。这不是我想要的。
我做错了吗?虽然我当然可以调用get() 或使用const_iterator,但我担心MyList 的用户会在不希望的情况下使用operator[]。有没有更好的运算符重载方法没有这个问题?
- 迭代器呢?我在迭代器中遇到了
operator*的类似问题。如果迭代器本身不是const,则始终调用第一个。
T& operator* ();
const T& operator* () const;
- 我的目标是在这个容器上运行
sort/nth_element/等C++ STL算法。如果我们考虑 C++ STL 算法的搜索阶段和交换阶段,在我看来,如果使用正确的迭代器,如果数据大部分已经排序,那么排序速度可能会更快。
MyList<int> list;
// ...
std::sort (list.begin (), list.end ());
如果数据没有改变,有没有办法最小化设置脏位的块数?
你能提供任何关于看/关注/学习什么的建议吗?或者这是语言或编译器的限制?
【问题讨论】:
-
“但是,如果 MyList 不是 const 版本,G++ 似乎会调用第一个。” - 这就是
const关键字在应用于类方法。在重载解析期间,编译器将根据调用实例的 const-ness 选择适当的函数。 -
在非常量设置中,
operator[]传统上用于 getting 和 setting。也就是说,myValue = list[0]和list[0] = myValue. -
副手:返回一个代理对象,当分配给
T类型的对象时,通过operator T展开(并且从不设置dirty),并且当分配一个@类型的元素时987654344@(operator=(T t)调用)进行更改并设置dirty? -
这是我对 C++ 的抱怨之一:IMO 应该有一个
operator[]=就像在 Ruby 中一样。 -
const函数仅在调用它的对象是const或没有非常量重载时才被调用。
标签: c++