让Memeber
为一类,让我们假设我不知道它是否支持或需要移动语义。出于所有意图和目的,可以说它尚未指定/编写。我应该在具有SetMember
作为成员的Outer
类中实现哪种Member
函数?
如果Member
不支持移动,我会这样做:
class Member {
public:
Member(Member&&) = delete;
Member& operator=(Member&&) = delete;
};
class Outer {
Member m_member;
public:
void SetMember(const Member& o) { m_member = o.m_member; } // makes a copy
};
如果Member
支持搬家,我会这样做:
class Member {
public:
Member(Member&&);
Member& operator=(Member&&);
};
class Outer {
Member m_member;
public:
void SetMember(Member o) { m_member = std::move(o.m_member); } // makes a copy if needed
};
但是由于我不知道它是否已移动,我是否需要同时实现两者?像这样:
class Outer {
Member m_member;
public:
void SetMember(const Member& o) { m_member = o.m_member; } // makes a copy
void SetMember(Member&& o) { m_member = std::move(o.m_member); } // makes no copy
};
还是我应该这样做?
class Outer {
Member m_member;
public:
template <class T>
void SetMember(T&& o) { m_member = std::forward<T>(o.m_member); }
};
为什么我对这两种解决方案不满意:
Member
的某些实现细节,即它是否支持move。SetMember
时都遇到编译错误,而不是智能感知错误。我还需要一个模板,只是因为Member
的一些实现细节。处理这种情况的干净方法是什么?
答案 0 :(得分:0)
据我所知,不再建议按值传值。至少在std::strings
的情况下,当多次调用setter时,很有可能目标变量为新值保留了足够的内存,并且将内容复制到已分配的字符串中然后创建一个临时字符串会更便宜并移动它。
因此,无论类型是否可移动,都建议通过const引用传递并在setter内进行复制。如果以后的分析表明经常使用临时变量作为参数,并且复制的开销使其值得优化,则可能会添加右值引用的重载。
另请参见https://stackoverflow.com/a/26286741/113662