Search code examples
c++c++11pass-by-valueperfect-forwarding

std::forward with pass-by-value argument


I was reading about encapsulated polymorphism and I came across a piece of code like that:

template <typename T>
struct Model<T> : Concept
{
    Model<T>(T impl) :
        mImpl(std::forward<T>(impl))
    {

    }
    virtual Concept* clone() const override
    {
        return new Model<T>(mImpl)
    }

    virtual void operator (const LogMessage::Meta& meta, const std::string& message) override
    {
        mImpl(meta, message);
    }

    T mImpl;
};

What is the point of forwarding impl in Model constructor?

Does it make sense to forward an argument if it is passed by value?


Solution

  • If Model<T> where T is an lvalue reference type (e.g. X&) is legal (according to Model's documentation), then forward is the correct tool to use here. Otherwise (if T should always be an object type), move is the correct tool.

    That being said, the clone member function makes it look like T should only be an object type. And so move would be a better tool to use here. And in this case forward isn't technically wrong, but simply confusing as it raises exactly the question the OP asks.