mardi 29 mai 2018

Performance comparison: f(std::string&&) vs f(T&&)

I'm trying to understand the performance implications of using WidgetURef::setName (URef being a Universal Reference, the term coined by Scott Meyers) vs WidgedRRef::setName (RRef being an R-value Reference):

#include <string>

class WidgetURef {
    public:
    template<typename T>
    void setName(T&& newName)
    {
        name = std::move(newName);
    }
    private:
        std::string name;
};

class WidgetRRef {
    public:
    void setName(std::string&& newName)
    {
        name = std::move(newName);
    }
    private:
        std::string name;
};

int main() {
    WidgetURef w_uref;
    w_uref.setName("Adela Novak");

    WidgetRRef w_rref;
    w_rref.setName("Adela Novak");
}

I do appreciate that with universal references one should be using std::forward instead, but this is just an (imperfect) example to highlight the interesting bit.

Question In this particular example, what is the performance implications of using one implementation vs the other? Although WidgetURef requires type deduction, it's otherwise identical to WidgetRRef, isn't it? At least in this particular scenario, in both cases the argument is an r-value reference, so no temporaries are created. Is this reasoning correct?

Context The example was taken from Item25 of Scott Meyers' "Effective Modern C++" (p. 170). According to the book (provided that my understanding is correct!), the version taking a universal reference T&& doesn't require temporary objects and the other one, taking std::string&&, does. I don't really see why.

Aucun commentaire:

Enregistrer un commentaire