1

これが私のコードです

#include <iostream>
#include <vector>
int main()
{
  std::vector<size_t> v1, v2;
  v1.push_back(3);
  v1.push_back(4);
  v2 = static_cast<std::vector<size_t>&&>(v1);
  std::cout << v1.size() << '\n';
  std::cout << v2.size() << '\n';  
}

--std=c++0x を指定して GCC 4.7.0 または clang 3.1 を使用して Linux でコードをコンパイルすると、0 と 2 が出力されました。 --std=c++0x を指定して clang 3.0 または clang 3.1 を実行すると、2 と 2 が出力されます。私の Mac OS X と FreeBSD の GCC は v4.2.1 で、--std=c++0x をサポートしていません。そこで、Boost.Move を使用しました。

#include <boost/move/move.hpp>
v2 = boost::move(v1);

-I~/boost_1_49_0 を指定して GCC 4.2.1 を使用して Mac OS X でコードをコンパイルすると、まだ 2 と 2 が出力されます。

更新: --stdlib=libc++ を追加すると、コードは 0 と 2 を出力しました。右辺値の参照は機能しているように見えました。しかし、ベクトル型を size_t から string に変更すると、コードの最後の 3 行をコメントしたにもかかわらず、コンパイル エラーが発生しました。今回の問題は Rvalue 参照とは関係なく、push_back() 関数に起因していました。--stdlib=libc++ を削除すると、コンパイルに合格する可能性があります。

#include <iostream>
#include <string>
#include <vector>
int main()
{
  std::vector<std::string> v1, v2;
  v1.push_back("hello");
  /*
  v2 = static_cast<std::vector<std::string>&&>(v1);
  std::cout << v1.size() << '\n';
  std::cout << v2.size() << '\n';  
  */
}

どのクラン

/uac/gds/hjli/clang+llvm-3.1-x86_64-apple-darwin11/bin/clang

clang++ --std=c++11 --stdlib=libc++ rval.cpp

In file included from rval.cpp:1:
In file included from /usr/include/c++/v1/iostream:38:
In file included from /usr/include/c++/v1/ios:216:
In file included from /usr/include/c++/v1/__locale:15:
/usr/include/c++/v1/string:1952:10: error: overload resolution selected
      implicitly-deleted copy assignment operator
    __r_ = _STD::move(__str.__r_);
         ^
/usr/include/c++/v1/string:1942:9: note: in instantiation of member function
      'std::__1::basic_string<char, std::__1::char_traits<char>,
      std::__1::allocator<char> >::__move_assign' requested here
        __move_assign(__str, true_type());
        ^
/usr/include/c++/v1/string:1961:5: note: in instantiation of member function
      'std::__1::basic_string<char, std::__1::char_traits<char>,
      std::__1::allocator<char> >::__move_assign' requested here
    __move_assign(__str, integral_constant<bool,
    ^
/usr/include/c++/v1/algorithm:1595:19: note: in instantiation of member function
      'std::__1::basic_string<char, std::__1::char_traits<char>,
      std::__1::allocator<char> >::operator=' requested here
        *__result = _STD::move(*__first);
                  ^
/usr/include/c++/v1/algorithm:1619:12: note: in instantiation of function
      template specialization 'std::__1::__move<std::__1::basic_string<char> *,
      std::__1::basic_string<char> *>' requested here
    return _STD::__move(__unwrap_iter(__first), __unwrap_iter(__last),...
           ^
/usr/include/c++/v1/__config:153:14: note: expanded from macro '_STD'
#define _STD std::_LIBCPP_NAMESPACE
             ^
/usr/include/c++/v1/__split_buffer:557:22: note: in instantiation of function
      template specialization 'std::__1::move<std::__1::basic_string<char> *,
      std::__1::basic_string<char> *>' requested here
            __end_ = _STD::move(__begin_, __end_, __begin_ - __d);
                     ^
/usr/include/c++/v1/__config:153:14: note: expanded from macro '_STD'
#define _STD std::_LIBCPP_NAMESPACE
             ^
/usr/include/c++/v1/vector:1289:13: note: in instantiation of member function
      'std::__1::__split_buffer<std::__1::basic_string<char>,
      std::__1::allocator<std::__1::basic_string<char> > &>::push_back'
      requested here
        __v.push_back(_STD::move(__x));
            ^
rval.cpp:10:5: note: in instantiation of member function
      'std::__1::vector<std::__1::basic_string<char>,
      std::__1::allocator<std::__1::basic_string<char> > >::push_back' requested
      here
        v1.push_back("nice");
           ^
/usr/include/c++/v1/memory:1941:5: note: copy assignment operator is implicitly
      deleted because '__compressed_pair<std::__1::basic_string<char,
      std::__1::char_traits<char>, std::__1::allocator<char> >::__rep,
      std::__1::allocator<char> >' has a user-declared move constructor
    __compressed_pair(__compressed_pair&& __p)
    ^
1 error generated.
4

2 に答える 2

3

GCC 4.2 は古くからあるため、std::vector右辺値参照をサポートしていません。を使用boost::moveしてもそれは変わりません。右辺値参照サポートをサポートしていないコンパイラ + ライブラリに魔法のように追加することはできません。つまり、移動ではなくコピーを行います。

Mac で Clang を使用する場合、GCC 4.2 の古い標準ライブラリを使用していると思われます。これは、コンパイラがサポートしていても、まだ右辺値参照をサポートしていません。代わりに、C++11 対応の libc++ ライブラリを使用できますか?

Linux で Clang を使用すると、C++11 をサポートする GCC 4.7 の標準ライブラリが使用されます。

NB Clang 3.1 と GCC 4.7 はどちらも-std=c++11の代わりにサポート-std=c++0xしていますが、Clang 3.0 もサポートしていると思います。すべてのコンパイラがオプションに新しい名前を使用している場合は、それを使用することもできます。

于 2012-06-16T10:52:42.333 に答える
0
rvalue_reference boost::move(input_reference)

この関数は、右辺値参照を使用するコンパイラで参照を右辺値参照に変換する方法を提供します。他のコンパイラでは、ムーブ エミュレーションがアクティブになるように変換T&されます。::boost::rv<T>&

std::vector::operator=(boost::rv&) が定義されていない場合、通常のコピー構築にフォールバックしている可能性があります。クラスでboost::rvsを処理するには、何か特別なことをしなければならないと思います

于 2012-06-16T06:55:54.597 に答える