首页 > 解决方案 > 性能比较:f(std::string&&) vs f(T&&)

问题描述

我试图了解使用WidgetURef::setNameURef作为通用参考,Scott Meyers 创造的术语)与WidgedRRef::setNameRRef作为 R 值参考)的性能影响:

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

我确实很欣赏应该使用通用引用来std::forward代替,但这只是一个(不完美的)示例来突出有趣的部分。

问题 在这个特定示例中,使用一种实现与另一种实现的性能影响是什么?虽然WidgetURef需要类型推导,但在其他方面与 相同WidgetRRef,不是吗?至少在这种特殊情况下,在这两种情况下,参数都是r-value引用,因此不会创建临时对象。这个推理正确吗?

上下文 该示例取自 Scott Meyers 的“Effective Modern C++”(第 170 页)的 Item25。根据这本书(前提是我的理解是正确的!),采用通用引用的版本T&&不需要临时对象,而另一个版本则需要std::string&&。我真的不明白为什么。

标签: c++c++11rvalue-reference

解决方案


setName(T&& newName)with 参数"Adela Novak"得到 T 推断const char (&)[12],然后分配给std::string.

setName(std::string&& newName)with 参数"Adela Novak"创建一个临时std::string对象,然后将其分配给std::string.

第一个在这里更有效,因为不涉及移动。


推荐阅读