C++ 中模板类的重载 [] 运算符具有常量/非常量版本
哇,那是一个很长的标题。
这是我的问题。我有一个 C++ 模板类,并且正在重载 [] 运算符。我有 const 和非常量版本,非常量版本通过引用返回,以便可以按如下方式更改类中的项目:
myobject[1] = myvalue;
这一切都有效,直到我使用布尔值作为模板参数。这是显示错误的完整示例:
#include <string>
#include <vector>
using namespace std;
template <class T>
class MyClass
{
private:
vector<T> _items;
public:
void add(T item)
{
_items.push_back(item);
}
const T operator[](int idx) const
{
return _items[idx];
}
T& operator[](int idx)
{
return _items[idx];
}
};
int main(int argc, char** argv)
{
MyClass<string> Test1; // Works
Test1.add("hi");
Test1.add("how are");
Test1[1] = "you?";
MyClass<int> Test2; // Also works
Test2.add(1);
Test2.add(2);
Test2[1] = 3;
MyClass<bool> Test3; // Works up until...
Test3.add(true);
Test3.add(true);
Test3[1] = false; // ...this point. :(
return 0;
}
该错误是编译器错误,消息是:
error: invalid initialization of non-const reference of type ‘bool&’ from a temporary of type ‘std::_Bit_reference’
我已阅读并发现 STL 使用一些临时数据类型,但我不明白为什么它适用于除 bool 之外的所有数据类型。
对此的任何帮助将不胜感激。
Whew, that was a long title.
Here's my problem. I've got a template class in C++ and I'm overloading the [] operator. I have both a const and a non-const version, with the non-const version returning by reference so that items in the class can be changed as so:
myobject[1] = myvalue;
This all works until I use a boolean as the template parameter. Here's a full example that shows the error:
#include <string>
#include <vector>
using namespace std;
template <class T>
class MyClass
{
private:
vector<T> _items;
public:
void add(T item)
{
_items.push_back(item);
}
const T operator[](int idx) const
{
return _items[idx];
}
T& operator[](int idx)
{
return _items[idx];
}
};
int main(int argc, char** argv)
{
MyClass<string> Test1; // Works
Test1.add("hi");
Test1.add("how are");
Test1[1] = "you?";
MyClass<int> Test2; // Also works
Test2.add(1);
Test2.add(2);
Test2[1] = 3;
MyClass<bool> Test3; // Works up until...
Test3.add(true);
Test3.add(true);
Test3[1] = false; // ...this point. :(
return 0;
}
The error is a compiler error and the message is:
error: invalid initialization of non-const reference of type ‘bool&’ from a temporary of type ‘std::_Bit_reference’
I've read up and found that STL uses some temporary data types, but I don't understand why it works with everything except a bool.
Any help on this would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
因为
vector
是专门针对STL的,实际上并不能满足标准容器的要求。Herb Sutter 在 GOTW 文章中对此进行了更多讨论:http://www.gotw.ca/gotw/ 050.htm
Because
vector<bool>
is specialized in STL, and does not actually meet the requirements of a standard container.Herb Sutter talks about it more in a GOTW article: http://www.gotw.ca/gotw/050.htm
vector
不是真正的容器。您的代码实际上试图返回对单个位的引用,这是不允许的。如果您将容器更改为deque
,我相信您会得到您期望的行为。A
vector<bool>
is not a real container. Your code is effectively trying to return a reference to a single bit, which is not allowed. If you change your container to adeque
, I believe you'll get the behavior you expect.vector
不像所有其他向量那样实现,也不像它们那样工作。你最好干脆不使用它,也不用担心你的代码是否无法处理它的许多特性 - 它通常被认为是一件坏事,是由一些不加思考的 C++ 标准委员会成员强加给我们的。A
vector<bool>
is not implemented like all other vectors, and does not work like them either. You are better off simply not using it, and not worrying if your code can't handle its many peculiarities - it is mostly considered to be A Bad Thing, foisted on us by some unthinking C++ Standard committee members.对你的班级进行一些简单的更改应该可以解决这个问题。
Some monor changes to your class should fix it.
正如其他答案指出的那样,提供了专门化来优化向量<向量的情况下的空间分配。布尔>。
但是,如果您使用 vector::reference 而不是 T&,您仍然可以使代码有效。事实上,在引用 STL 容器保存的数据时,使用 container::reference 是一个很好的做法。
当然,
还有一个用于 const 引用的 typedef:
并且这个变为(删除无用的额外副本)
As the other answers point out, a specialization is provided to optimize for space allocation in the case of vector< bool>.
However you can still make your code valid if you make use of vector::reference instead of T&. In fact it is a good practice to use container::reference when referencing data held by a STL container.
becomes
Of course ther is also a typedef for const reference:
and this one becomes (removing the useless extra copy)
错误的原因是
vector
专门用于打包存储在其中的布尔值,并且vector::operator[]
返回某种代理让您访问该值。我认为解决方案不是返回与
vector::operator[]
相同的类型,因为那样你就只是将令人遗憾的特殊行为复制到容器中。如果您想继续使用
vector
作为基础类型,我相信 bool 问题可以通过使用vector
来解决,而不是在MyClass
时使用code> 使用bool
实例化。它可能看起来像这样:
The reason for the error is that
vector<bool>
is specialized to pack the boolean values stored within andvector<bool>::operator[]
returns some sort of proxy that lets you access the value.I don't think a solution would be to return the same type as
vector<bool>::operator[]
because then you'd be just copying over the regrettable special behavior to your container.If you want to keep using
vector
as the underlying type, I believe the bool problem could be patched up by using avector<MyBool>
instead whenMyClass
is instantiated withbool
.It might look like this: