C++ 在C+中将std::字符串移动到boost::线程中+;03

C++ 在C+中将std::字符串移动到boost::线程中+;03,c++,boost,boost-thread,stdstring,boost-move,C++,Boost,Boost Thread,Stdstring,Boost Move,我在没有C++11的多个平台和编译器上使用Boost1.51 在我的主线程中,我有一个非常长、非常昂贵的副本,std::stringveryLongString,我需要将其传递给一个新线程进行处理。 创建新线程后,我不再使用主线程上的veryLongString,因此我想将其移动到boost::thread选择器中。 主线程或veryLongString的作用域可能在新线程完成之前结束,因此通过引用传递(例如使用boost::ref)不是一个选项 显然,如果veryLongString被创建为s

我在没有C++11的多个平台和编译器上使用Boost1.51

在我的主线程中,我有一个非常长、非常昂贵的副本,
std::string
veryLongString
,我需要将其传递给一个新线程进行处理。
创建新线程后,我不再使用主线程上的
veryLongString
,因此我想将其移动到
boost::thread
选择器中。
主线程或
veryLongString
的作用域可能在新线程完成之前结束,因此通过引用传递(例如使用
boost::ref
)不是一个选项

显然,如果
veryLongString
被创建为
shared\u ptr
,那么我可以将
shared\u ptr
复制到线程ctor中,但它不是,所以我还是需要复制它

如何将()移动到
boost::thread
选择器(可能使用via
boost::bind
)中?
这是可能的吗?

您可以将其作为引用传递给构造函数,并在构造函数中使用
move
(甚至
swap
)来“移动”字符串。

如果字符串的复制成本很高,则传递保存它但复制成本较低的内容。例如,您可以使用
共享\u ptr
。您可以将共享指针传递给合适的包装器,该包装器调用您实际想要调用的函数(可能通过引用或
const
reference获取参数)

要将字符串放入共享指针,可能需要将其移动到共享指针:

shared_ptr<std::string> ptr(new std::string);
ptr->swap(your_long_string);
shared_ptr ptr(新std::string);
ptr->swap(您的长字符串);

我不确定我是否完全理解你的问题。但是如果我这样做了,那么一旦主线程超出范围,veryLongString就会随之消失,破坏字符串并在新线程内创建一个悬空引用。我更新了这个问题来反映这一点。这听起来像是您为某些特殊处理创建了一个线程,而不是一个与主线程分离的“守护进程”线程。因此,主线程将在处理线程之前退出的场景听起来很可疑。至于您的问题,为什么不将字符串作为引用传递给构造函数,并在构造函数中使用
boost::move
将内容移动到内部字符串?@Joachim Pileborg:实际上,它是一个异步调用,被发送去完成它的工作。完成后,它将调用完成处理程序/继续。主线程并没有真正退出,但是
veryLongString
确实超出了处理其他事情的范围。但是,我正在使用一个函数来完成这项工作。如果我使用一个可调用对象,我可以按照你的建议去做,我不知道为什么我没有想到这一点!我甚至不需要
boost::mov
e,我可以
swap
字符串。把你的第二条评论作为答案,我会把它标记为答案。我刚刚试过这个。这并不像我最初想的那么简单。虽然字符串被“移动”到了函子中,但将函子传递到线程中需要一个函子副本(不能通过ref传递),因此我需要编写一个特殊的副本,实际移动它,而不是复制。这确实很好。一个小小的优化就是使用
shared\u ptr ptr=make\u shared()
而不是
new
。swap的实现不会在非c++11编译器上复制吗?那么解决上述问题呢?副本是
共享的\u ptr
而不是
std::string
。因此,在调用线程实例超出范围之前,ref.count将暂时为2。我可能完全没有抓住这里的要点,但是如果在共享的\u ptr上调用swap,则应该像ptr.swap(您的\u long \u字符串)一样调用它。这不会编译,因为您的长字符串不是共享的\u ptr。可以使用两个
swap()
ptr。swap(p)
将交换共享指针,
ptr->swap(s)
将指向的字符串与另一个字符串交换
std::string
有一个交换内部指针的
swap()
成员(除非涉及可能需要移动字符的小字符串)。