[英]Does std::vector use the assignment operator of its value type to push_back elements?
如果是這樣,為什么? 為什么不使用值類型的復制構造函數?
我收到以下錯誤:
/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;
}
C ++ 03標准規定元素必須是可復制構造和可復制分配才能在標准容器中使用。 所以一個實現可以隨意使用它們想要的任何東西。
在C ++ 0x中,這些要求基於每個操作。 (通常,元素必須是可移動構造和可移動分配的。)
要得到你想要的東西,你應該使用像shared_ptr
這樣的智能指針(來自Boost,TR1或C ++ 0x),並完全禁用復制能力:
class ClassWithoutAss
{
public:
const int mem;
ClassWithoutAss(int mem):mem(mem){}
// don't explicitly declare empty destructors
private:
ClassWithoutAss(const ClassWithoutAss&); // not defined
ClassWithoutAss& operator=(const ClassWithoutAss&); // not defined
};
typedef shared_ptr<ClassWithoutAss> ptr_type;
std::vector<ptr_type> vec;
vec.push_back(ptr_type(new ClassWithoutAss(1)));
指針可以很好地復制,智能指針確保您不會泄漏。 在C ++ 0x中,你可以利用std::unique_ptr
做到最好,利用移動語義。 (你實際上並不需要共享語義,但在C ++ 03中它最簡單。)
這里的問題是容器中的類型必須是可分配的。
因為您沒有為您的類定義賦值運算符,所以編譯器將為您生成一個賦值運算符。 默認賦值運算符如下所示:
ClassWithoutAss& operator=(ClassWithoutAss const& rhs)
{
mem = copy.mem;
return *this;
}
// The compiler generated assignment operator will copy all members
// using that members assignment operator.
在大多數情況下,這可行。 但成員mem是一個const,因而無法分配。 因此,編譯在嘗試生成賦值運算符時將失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.