std::vector 是否使用其值类型的赋值运算符来 push_back 元素?
如果是这样,为什么?为什么不使用值类型的复制构造函数?
我收到以下错误:
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc: In member functio
n `ClassWithoutAss& ClassWithoutAss::operator=(const ClassWithoutAss&)':
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc:238: instantiate
d from `void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterato
r<typename _Alloc::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp =
ClassWithoutAss, _Alloc = std::allocator<ClassWithoutAss>]'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_vector.h:564: instantia
ted from `void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Class
WithoutAss, _Alloc = std::allocator<ClassWithoutAss>]'
main.cpp:13: instantiated from here
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc:238: error: non-st
atic const member `const int ClassWithoutAss::mem', can't use default assignment
operator
在以下代码上运行 g++ main.cpp:
/*
* ClassWithoutAss.h
*
*/
#ifndef CLASSWITHOUTASS_H_
#define CLASSWITHOUTASS_H_
class ClassWithoutAss
{
public:
const int mem;
ClassWithoutAss(int mem):mem(mem){}
ClassWithoutAss(const ClassWithoutAss& tobeCopied):mem(tobeCopied.mem){}
~ClassWithoutAss(){}
};
#endif /* CLASSWITHOUTASS_H_ */
/*
* main.cpp
*
*/
#include "ClassWithoutAss.h"
#include <vector>
int main()
{
std::vector<ClassWithoutAss> vec;
ClassWithoutAss classWithoutAss(1);
(vec.push_back)(classWithoutAss);
return 0;
}
If so, why? Why doesn't it use the copy constructor of the value type?
I get the following error:
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc: In member functio
n `ClassWithoutAss& ClassWithoutAss::operator=(const ClassWithoutAss&)':
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc:238: instantiate
d from `void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterato
r<typename _Alloc::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp =
ClassWithoutAss, _Alloc = std::allocator<ClassWithoutAss>]'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_vector.h:564: instantia
ted from `void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Class
WithoutAss, _Alloc = std::allocator<ClassWithoutAss>]'
main.cpp:13: instantiated from here
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc:238: error: non-st
atic const member `const int ClassWithoutAss::mem', can't use default assignment
operator
running g++ main.cpp on the following code:
/*
* ClassWithoutAss.h
*
*/
#ifndef CLASSWITHOUTASS_H_
#define CLASSWITHOUTASS_H_
class ClassWithoutAss
{
public:
const int mem;
ClassWithoutAss(int mem):mem(mem){}
ClassWithoutAss(const ClassWithoutAss& tobeCopied):mem(tobeCopied.mem){}
~ClassWithoutAss(){}
};
#endif /* CLASSWITHOUTASS_H_ */
/*
* main.cpp
*
*/
#include "ClassWithoutAss.h"
#include <vector>
int main()
{
std::vector<ClassWithoutAss> vec;
ClassWithoutAss classWithoutAss(1);
(vec.push_back)(classWithoutAss);
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
C++03 标准规定元素必须是可复制构造和可复制分配的才能在标准容器中使用。因此,一个实现可以自由地使用它想要的任何一个。
在 C++0x 中,这些要求是基于每个操作的。 (一般来说,元素必须是可移动构造和可移动分配的。)
为了得到你想要的,你应该使用像
shared_ptr
这样的智能指针(来自 Boost、TR1 或 C++0x) ,并完全禁用复制能力:指针可以很好地复制,并且智能指针可确保您不会泄漏。在 C++0x 中,您可以利用
std::unique_ptr
充分利用移动语义来做到这一点。 (您实际上不需要共享语义,但在 C++03 中它是最简单的。)The C++03 standard says elements must be copy-constructible and copy-assignable to be used in a standard container. So an implementation is free to use whichever it wants.
In C++0x, these requirements are put on a per-operation basis. (In general, elements must be move-constructible and move-assignable.)
To get what you want, you should use a smart pointer like
shared_ptr
(from either Boost, TR1, or C++0x), and completely disable copy-ability:Pointers can be copied just fine, and the smart pointer ensures you don't leak. In C++0x you can do this best with a
std::unique_ptr
, taking advantage of move-semantics. (You don't actually need shared semantics, but in C++03 it's easiest as it stands.)这里的问题是容器中的类型必须是可分配的。
因为您没有为您的类定义赋值运算符,所以编译器将为您生成一个赋值运算符。默认的赋值运算符如下所示:
在大多数情况下,这可以工作。但成员 mem 是一个常量,因此不可分配。因此,当编译尝试生成赋值运算符时,它将失败。
The problem here is that types in a container must be assignable.
Because you do not define an assignment operator for your class the compiler will generate one for you. The default assignment operator will look like this:
In most situations this would work. But the member mem is a const and thus unassignable. Therefore compilation will fail when it tries to generate the assignment operator.