我想编写一个优化参数的类。我认为以下界面是可取的:
class Optimization {
public:
std::shared_ptr<Part> getParameter() const {
return m_parameter;
}
void setParameter(const std::shared_ptr<Parameter>& parameter) {
m_parameter = parameter;
}
private:
std::shared_ptr<Paramter> m_parameter;
};
现在有时我可能对参数的起始值不感兴趣所以我想像这样调用setParameter:
setParameter(std::make_shared(Parameter(...)));
(现在我觉得为什么有一个getter函数更有意义) 据我所知,setParameter函数没有利用我将rvalue传递给setParameter。
所以我的问题是如何解决这个问题?
我应该添加其他功能
void setParameter(std::shared_ptr<Parameter>&& parameter) {
m_parameter = std::move(parameter);
}
这是否可以避免不必要的副本? 或者是一个普遍的参考,也许是这样的:
template<typename T>
void setParameter(T&& parameter) {
m_parameter = std::forward<T>(parameter);
}
是一个更好的解决方案吗?
答案 0 :(得分:2)
正确的实现如下
void setParameter(std::shared_ptr<Parameter> parameter) {
m_parameter = std::move(parameter);
}
parameter
,parameter
将移至m_parameter
。两个动作,就像你想要的那样。parameter
,parameter
将被移至m_parameter
。一个副本和一个移动,类似于const引用,加上便宜的移动将被优化。您可以在Scott Meyers的“Effective C ++”一书中阅读此内容。
答案 1 :(得分:1)
std::piecewise_construct
是一个constexpr标志,可用于指示数据对象的分段构造。
内联解释性意见
#include <memory>
#include <utility>
struct Parameter
{
// some constructor
Parameter(int, int);
};
class Optimization {
public:
std::shared_ptr<Parameter> getParameter() const {
return m_parameter;
}
// original overload
void setParameter(const std::shared_ptr<Parameter>& parameter) {
m_parameter = parameter;
}
// rvalue overload
void setParameter(std::shared_ptr<Parameter>&& parameter) {
m_parameter = std::move(parameter);
}
// piecewise overload which forwards arguments
template<typename...Args>
void setParameter(std::piecewise_construct_t, Args&&...args)
{
m_parameter = std::make_shared<Parameter>(std::forward<Args>(args)...);
}
private:
std::shared_ptr<Parameter> m_parameter;
};
int main()
{
auto o = Optimization();
// original
o.setParameter(std::make_shared<Parameter>(1,2));
// equivalent to...
o.setParameter(std::piecewise_construct, 1, 2);
}