shared_ptr的setter函数

时间:2018-04-02 14:52:36

标签: c++ smart-pointers rvalue-reference

我想编写一个优化参数的类。我认为以下界面是可取的:

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);
        }

是一个更好的解决方案吗?

2 个答案:

答案 0 :(得分:2)

正确的实现如下

void setParameter(std::shared_ptr<Parameter> parameter) {
    m_parameter = std::move(parameter);
}
  1. rvalue将移至parameterparameter将移至m_parameter。两个动作,就像你想要的那样。
  2. 左值将被复制到parameterparameter将被移至m_parameter。一个副本和一个移动,类似于const引用,加上便宜的移动将被优化。
  3. 您可以在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);
}