这一项工作
std::pair<std::vector<std::string>, int> move_pair()
{
std::vector<std::string> temp;
//do some jobs
return std::make_pair(std::move(temp), 0);
}
但是这个不行(不能用boost :: move来移动temp)
std::pair<boost::container::vector<std::string>, int> move_pair()
{
boost::container::vector<std::string> temp;
//do some jobs
return std::make_pair(boost::move(temp), 0);
}
无论如何用std :: pair的c ++ 98/03编译器来移动boost :: container的temp? 是否存在boost :: container :: pair,boost :: container :: make_pair?
错误消息
..\networkLibTest\main.cpp(18) : error C2248: 'boost::rv<T>::rv' : cannot access private member declared in class 'boost::rv<T>'
with
[
T=boost::container::vector<std::string>
]
g:\Tools\3rdLibs\boost\boost_1_55_0\boost/move/core.hpp(71) : see declaration of 'boost::rv<T>::rv'
with
[
T=boost::container::vector<std::string>
]
..\networkLibTest\main.cpp(18) : error C2248: 'boost::rv<T>::~rv' : cannot access private member declared in class 'boost::rv<T>'
with
[
T=boost::container::vector<std::string>
]
g:\Tools\3rdLibs\boost\boost_1_55_0\boost/move/core.hpp(70) : see declaration of 'boost::rv<T>::~rv'
with
[
T=boost::container::vector<std::string>
]
答案 0 :(得分:3)
boost::move
通过将提供的引用的类型基本上转换为不同的“包裹”类型来模拟C ++ 98模式中的移动语义,该类型表示“嘿,我是一个右手,从我这里抢走!”。
但是,为了实现这一点,类型的构造函数/赋值运算符必须能够识别这种“包装”类型并相应地执行,这意味着这需要来自类型的协作。
std::vector
显然对提升一无所知,非合作类型的boost::move
实现只返回传递给它的内容,所以你的代码用std::vector
编译,但实际上是复制的而不是移动。
虽然boost::container::vector
是一种协作类型,但移动语义模拟使用的包装类型不可构造,可复制,甚至可以破坏 - boost::move
返回的引用是通过{{1}获得的传入的引用。因此,你不能使用返回值为static_cast
的C ++ 03 make_pair
,因为C ++ 03 boost::move
按值获取其参数,会尝试制作包装类型的副本,并努力工作。如果您使用make_pair
,您可以做的最好是直接调用boost::move
的构造函数:
std::pair
将return std::pair<boost::container::vector<std::string>, int>(boost::move(temp), 0);
移动到临时temp
并将该临时文件传递给boost::container::vector<std::string>
的构造函数,但由于std::pair
的构造函数通过std::pair
获取其参数引用而不是按值,因此无论如何都会制作副本,这样做是没有意义的。
答案 1 :(得分:0)
我只是提出一个天真的对和make_pair,不知道这个实现是否隐藏了任何陷阱
pair.hpp
namespace wlg{
template<typename T1, typename T2>
class pair
{
public:
typedef T1 first_type;
typedef T2 second_type;
pair(T1 const &fir, T2 const &sec);
pair(BOOST_RV_REF(T1) fir, T2 const &sec);
pair(T1 const &first, BOOST_RV_REF(T2) sec);
pair(BOOST_RV_REF(T1) fir, BOOST_RV_REF(T2) sec) :
first(boost::move(fir)),
second(boost::move(sec))
{
#ifdef WLG_PAIR_DEBUG_ENABLE
std::cout<<"pair(BOOST_RV_REF(T1) first, BOOST_RV_REF(T2) second)"<<std::endl;
#endif
}
pair(pair const &data);
pair(BOOST_RV_REF(pair) data) //Move constructor
: first(boost::move(data.first)),
second(boost::move(data.second))
{
#ifdef WLG_PAIR_DEBUG_ENABLE
std::cout<<"pair(BOOST_RV_REF(pair) data)"<<std::endl;
#endif
}
pair& operator=(BOOST_COPY_ASSIGN_REF(pair) data);
pair& operator=(BOOST_RV_REF(pair) data) //Move assignment
{
#ifdef WLG_PAIR_DEBUG_ENABLE
std::cout<<"operator=(BOOST_RV_REF(pair) data)"<<std::endl;
#endif
if (this != &data){
first = boost::move(data.first);
second = boost::move(data.second);
}
return *this;
}
void swap(pair &data)
{
swap(data.first, first);
swap(data.second, second);
}
private:
template<class T>
void swap(T &fir, T &sec)
{
T tmp(::boost::move(fir));
fir = ::boost::move(sec);
sec = ::boost::move(tmp);
}
public:
T1 first;
T2 second;
private:
BOOST_COPYABLE_AND_MOVABLE(pair)
};
template<typename T1, typename T2>
pair<T1, T2>::pair(const T1 &fir, const T2 &sec) :
first(fir),
second(sec)
{
#ifdef WLG_PAIR_DEBUG_ENABLE
std::cout<<"pair(const T1 &first, const T2 &second)"<<std::endl;
#endif
}
template<typename T1, typename T2>
pair<T1, T2>::pair(BOOST_RV_REF(T1) fir, const T2 &sec) :
first(boost::move(fir)),
second(sec)
{
#ifdef WLG_PAIR_DEBUG_ENABLE
std::cout<<"pair(BOOST_RV_REF(T1) first, const T2 &second)"<<std::endl;
#endif
}
template<typename T1, typename T2>
pair<T1, T2>::pair(const T1 &fir, BOOST_RV_REF(T2) sec) :
first(fir),
second(boost::move(sec))
{
#ifdef WLG_PAIR_DEBUG_ENABLE
std::cout<<"pair(const T1 &first, BOOST_RV_REF(T2) second)"<<std::endl;
#endif
}
template<typename T1, typename T2>
pair<T1, T2>::pair(const pair &data) :
first(data.first),
second(data.second)
{
#ifdef WLG_PAIR_DEBUG_ENABLE
std::cout<<"pair(const pair &data)"<<std::endl;
#endif
}
template<typename T1, typename T2>
inline
pair<T1, T2> make_pair(T1 const &fir, T2 const &sec)
{
#ifdef WLG_PAIR_DEBUG_ENABLE
std::cout<<"make_pair(T1 const &first, T2 const &second)"<<std::endl;
#endif
return pair<T1, T2>(fir, sec);
}
template<typename T1, typename T2>
inline
pair<T1, T2> make_pair(BOOST_RV_REF(T1) fir, T2 const &sec)
{
#ifdef WLG_PAIR_DEBUG_ENABLE
std::cout<<"make_pair(BOOST_RV_REF(T1) first, T2 const &second)"<<std::endl;
#endif
return pair<T1, T2>(boost::move(fir), sec);
}
template<typename T1, typename T2>
inline
pair<T1, T2> make_pair(T1 const &fir, BOOST_RV_REF(T2) sec)
{
#ifdef WLG_PAIR_DEBUG_ENABLE
std::cout<<"make_pair(T1 const &first, BOOST_RV_REF(T2) second)"<<std::endl;
#endif
return pair<T1, T2>(fir, boost::move(sec));
}
template<typename T1, typename T2>
inline
pair<T1, T2> make_pair(BOOST_RV_REF(T1) fir, BOOST_RV_REF(T2) sec)
{
#ifdef WLG_PAIR_DEBUG_ENABLE
std::cout<<"make_pair(BOOST_RV_REF(T1) first, BOOST_RV_REF(T2) second)"<<std::endl;
#endif
return pair<T1, T2>(boost::move(fir), boost::move(sec));
}
template<typename T1, typename T2>
inline
bool operator==(pair<T1, T2> const &fir, pair<T1, T2> const &sec)
{
return fir.first == sec.first && fir.second == sec.second;
}
template<typename T1, typename T2>
inline
bool operator!=(pair<T1, T2> const &fir, pair<T1, T2> const &sec)
{
return !(fir == sec);
}
template<typename T1, typename T2>
inline
bool operator>=(pair<T1, T2> const &fir, pair<T1, T2> const &sec)
{
return fir.first >= sec.first && fir.second >= sec.second;
}
template<typename T1, typename T2>
inline
bool operator<=(pair<T1, T2> const &fir, pair<T1, T2> const &sec)
{
return !(fir >= sec);
}
template<typename T1, typename T2>
inline
bool operator>(pair<T1, T2> const &fir, pair<T1, T2> const &sec)
{
return fir.first > sec.first && fir.second > sec.second;
}
template<typename T1, typename T2>
inline
bool operator<(pair<T1, T2> const &fir, pair<T1, T2> const &sec)
{
return !(fir > sec);
}
}
测试代码
#define WLG_PAIR_DEBUG_ENABLE
#include "pair.h"
#include <boost/container/vector.hpp>
#include <boost/move/move.hpp>
#include <string>
Type make_pair_00()
{
boost::container::vector<std::string> temp_1;
boost::container::vector<std::string> temp_2;
return wlg::make_pair(temp_1, temp_2);
}
Type make_pair_01()
{
boost::container::vector<std::string> temp_1;
boost::container::vector<std::string> temp_2;
return wlg::make_pair(boost::move(temp_1), temp_2);
}
Type make_pair_02()
{
boost::container::vector<std::string> temp_1;
boost::container::vector<std::string> temp_2;
return wlg::make_pair(temp_1, boost::move(temp_2));
}
Type make_pair_03()
{
boost::container::vector<std::string> temp_1;
boost::container::vector<std::string> temp_2;
return wlg::make_pair(boost::move(temp_1), boost::move(temp_2));
}
int main()
{
Type target_00 = make_pair_00();
std::cout<<std::endl;
Type target_01 = make_pair_01();
std::cout<<std::endl;
Type target_02 = make_pair_02();
std::cout<<std::endl;
Type target_03 = make_pair_03();
std::cout<<std::endl;
Type target_04 = boost::move(target_00);
std::cout<<std::endl;
target_00 = make_pair_00();
std::cout<<std::endl;
}
结果
make_pair(T1 const &first, T2 const &second)
pair(const T1 &first, const T2 &second)
make_pair(BOOST_RV_REF(T1) first, T2 const &second)
pair(BOOST_RV_REF(T1) first, const T2 &second)
make_pair(T1 const &first, BOOST_RV_REF(T2) second)
pair(const T1 &first, BOOST_RV_REF(T2) second)
make_pair(BOOST_RV_REF(T1) first, BOOST_RV_REF(T2) second)
pair(BOOST_RV_REF(T1) first, BOOST_RV_REF(T2) second)
pair(BOOST_RV_REF(pair) data)
make_pair(T1 const &first, T2 const &second)
pair(const T1 &first, const T2 &second)
operator=(BOOST_RV_REF(pair) data)
target_00~target_03不调用任何拷贝构造函数,也许它是由RVO优化的?