【发布时间】:2015-06-16 19:47:15
【问题描述】:
假设我有这门课:
class Message
{
public:
using Payload = std::map<std::string, boost::any>;
Message(int id, Payload payload)
: id_(id),
payload_(std::move(payload))
{}
int id() const {return id_;}
const Payload& payload() const {return payload_;}
private:
int id_;
Payload payload_;
};
Payload 可能很大且复制成本很高。
我想让Message 类的用户有机会移动有效负载,而不必复制它。这样做的最佳方法是什么?
我可以想到以下几种方式:
-
添加一个
Payload& payload()重载,它返回一个可变引用。然后用户可以这样做:Payload mine = std::move(message.payload()) 不要再假装我正在封装
payload_,而是将其设为公共成员。-
提供一个
takePayload成员函数:Payload takePayload() {return std::move(payload_);} -
提供这个备用成员函数:
void move(Payload& dest) {dest = std::move(payload_);} -
(由Tavian Barnes 提供)提供使用ref-qualifier 的
payloadgetter 重载:const Payload& payload() const {return payload_;}Payload payload() && {return std::move(payload_);}
替代方案 #3 似乎是 std::future::get 中所做的,重载 (1)。
任何关于最佳替代方案(或另一种解决方案)的建议将不胜感激。
编辑:以下是我想要完成的一些背景知识。在我的实际工作中,这个 Message 类是一些通信中间件的一部分,并且包含用户可能感兴趣或可能不感兴趣的一堆其他元数据。我曾认为用户可能希望将有效负载数据移动到他的或者她自己的数据结构,收到后丢弃原来的Message对象。
【问题讨论】:
-
“最佳”一般来说似乎有点主观。就可读性而言,备选方案#3 对我来说似乎是最好的。另外,为什么不为整个
Message类实现/使用移动语义? -
我认为这在很大程度上取决于为什么用户想要移动(或者,事实上,甚至访问)该成员。为什么这个类不是所有者?
-
@Steephen 这个问题和这个有什么关系?这是从班级成员那里转移过来的;它必须是明确的。
-
另一个选择是
Payload payload() && {return std::move(payload_); } -
@Steephen:我相信另一个问题,其动机是防止临时复制。在我的情况下,我故意希望用户能够移动私有成员变量,以便它从最初托管它的对象中永久“消失”。
标签: c++ c++11 move encapsulation