5

私はいくつかのコードを持っています:

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のcopyctorの代わりにmoveコンストラクターを呼び出したいです。このコードは正しいですか?そう思います。奇妙なことに、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]’

copyctorを呼び出そうとしているようです。このエラーに関するアイデアはありますか?

私の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)

更新:「セマンティック移動」の使用法に誤りがあるかもしれません。STL文字列で「移動」してみました。

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

それは大丈夫で、内部の文字は本当に「移動」しています。

しかし、それは私のクラスAでは機能しません...これはAです:

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

更新:Aが次の場合、動作しました:

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

COPYCTORに注意してください。これで、すべての移動セマンティクスが正しく機能し、実行時にcopyctorが実際に呼び出されなくなりました。「移動」について間違っていますか?

4

2 に答える 2

7

のテンプレート引数を指定しないでくださいstd::make_pair。完全な転送メカニズムが無効になります。つまり、を使用できない場合は、次のようにemplace呼び出すだけです。make_pair

bla.insert(make_pair(1, move(tmp)));
于 2012-07-17T16:24:13.273 に答える
-1

この質問はこの質問と同じ答えであり、重複した質問である可能性があると思います。

ただし、move contstructorでnoexceptキーワードを使用すると、まだ正常にコンパイルできません。

于 2012-07-26T06:41:44.083 に答える