4

从 Efficient Modern C++ 开始工作,第 25 条。我们有一个例子

情况1

class Widget {
public:
template<typename T>
void setName(T&& newName)
{ name = std::forward<T>(newName); }
...
};

案例2

class Widget {
public:
void setName(const std::string& newName)
{ name = newName; }
void setName(std::string&& newName)
{ name = std::move(newName); }
...
};

通话

Widget w;
w.setName("Adela Novak");

现在假设情况 1,该书指出文字被传送到 w 的 name 数据成员内的 t std::string 的赋值运算符。

假设情况 2,这本书指出 -> 首先从文字创建一个临时,调用字符串构造函数,因此 setName 参数可以绑定到它,然后这个临时被移动到 w 的 name 数据成员中。

问题

为什么会出现这种行为差异,我该如何思考?

即,为什么在案例 1 中不需要临时的?为什么有区别?T&& 是否被推断为对字符串的右值引用,从而达到与案例 2 相同的行为(显然不是,根据书,但为什么)?

4

1 回答 1

9

在情况 1 中,T推断为const char (&)[12],不是std::string。编译器还没有理由将字符串文字提升为std::string尚未。在情况 2 中,每个重载 requires 都需要一个对 an 的引用std::string,这会强制创建一个std::string可以使用隐式const char*构造函数将引用绑定到的临时对象。

请注意,虽然右值引用(例如)std::string &&只能绑定到右值,但模板化的等效T &&项可以同时绑定到右值和左值。

于 2018-01-29T20:36:56.783 回答