2012-07-17 42 views
4

移動構造函數我有一些代碼:與unordered_map

Class A{ 
//...A has a move ctor here. 
}; 

unordered_map<int, A> bla; 
A tmp; 
//operations on tmp 
bla.insert(make_pair<int, A>(1, move(tmp))); 

我想呼叫轉移構造函數,而不是A級的副本構造函數是這個代碼是否正確? 我這麼認爲。奇怪的是它爲Ubuntu Precise編譯和工作(g ++ show version of 4.6.3)。但在CentOS上,它未能編譯。前幾行是:

In substitution of ‘template<class _From1, class _To1> static decltype  ((__test_aux<_To1>(declval<_From1>()), std::__sfinae_types::__one()))  std::__is_convertible_helper<_From, _To, false>::__test(int) [with _From1 = _From1; _To1 = _To1; _From = const A&; _To = A] [with _From1 = const A&; _To1 = A]’: 
/gcc/x86_64-redhat-linux/4.7.1/../../../../include/c++/4.7.1/type_traits:1258:70: required from ‘constexpr const bool std::__is_convertible_helper<const A&, A, false>::value’ 
/gcc/x86_64-redhat-linux/4.7.1/../../../../include/c++/4.7.1/type_traits:1263:12: required from ‘struct std::is_convertible<const A&, A>’ 
/gcc/x86_64-redhat-linux/4.7.1/../../../../include/c++/4.7.1/type_traits:116:12: required from ‘struct std::__and_<std::is_convertible<const int&, int>, std::is_convertible<const A&, A> >’ 
/gcc/x86_64-redhat-linux/4.7.1/../../../../include/c++/4.7.1/bits/stl_pair.h:113:38: required from ‘constexpr std::pair<typename std::__decay_and_strip<_T1>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&) [with _T1 = int; _T2 = A; typename std::__decay_and_strip<_T2>::__type = A; typename std::__decay_and_strip<_T1>::__type = int]’ 

它似乎試圖調用複製ctor。關於這個錯誤的任何想法?

那麼,我的CentOS沒有最新版本的gcc/libstdC++,所以實際上我自己構建這些(gcc 4.7.1),並將它們安裝在我的主目錄中。這很重要嗎?這是編譯時我的配置:

Target: x86_64-redhat-linux 
Configured with: ../gcc-4.7.1/configure --prefix=/home/bla/usr/ --with-mpc=/home/bla/usr/ --with-mpfr=/home/bla/usr/ --with-gmp=/home/bla/usr/ --disable-multilib --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++ --enable-java-awt=gtk --disable-dssi --disable-plugin --with-cpu=generic --build=x86_64-redhat-linux 
Thread model: posix 
gcc version 4.7.1 (GCC) 

UPDATE: 也許有某事錯的「移動語義」的使用。我試着用STL字符串「移動」:

unordered_map<int, string> bla; 
string tmp("hello world"); 
//operations on tmp 
bla.emplace(1, move(tmp)); 

這樣就好了,內部字符真的「移動」了。

不過,這並不與我的A級工作...這是一個:

class A 
{ 
    public: 
     A(){...} 
     ~A(){} 
     A(A&& other){...} 
    private: 
     A& operator = (const A& other); 
     A& operator = (A&& other); 
     A(const A& other); 
}; 

UPDATE: 我得到它的工作,當A爲:

class A 
{ 
    public: 
     A(){...} 
     ~A(){} 
     A(A&& other){...} 
     A(const A& other){} 
    private: 
     A& operator = (const A& other); 
     A& operator = (A&& other); 
}; 

講究到COPY CTOR。現在我所有的移動語義工作都是正確的,並且拷貝ctor在運行時實際上並不叫。我對「移動」有錯嗎?

+0

舊的gcc版本? – 2012-07-17 12:41:43

+0

在Arch Linux上用g ++ 4.7.1測試過,效果很好。 – rodrigo 2012-07-17 12:43:28

+6

實際上,如果libstdC++版本足夠新,您應該使用'.emplace'。 'bla.emplace(1,std :: move(tmp))'。 – kennytm 2012-07-17 14:13:30

回答

-1

我認爲,這個問題有相同的答案this question和可重複的問題。

但是,當使用noexcept關鍵字移動contstructor時,我仍然沒有成功編譯它。

5

不要指定std::make_pair的模板參數,因爲這會破壞其完美轉發機制。也就是說,如果您不能使用emplace,則只需撥打make_pair如下:

bla.insert(make_pair(1, move(tmp)));