在 Item 41 中,Scott Meyers 编写了以下两个类:
class Widget {
public:
void addName(const std::string& newName) // take lvalue;
{ names.push_back(newName); } // copy it
void addName(std::string&& newName) // take rvalue;
{ names.push_back(std::move(newName)); } // move it; ...
private:
std::vector<std::string> names;
};
class Widget {
public:
template<typename T> // take lvalues
void addName(T&& newName) // and rvalues;
{ // copy lvalues,
names.push_back(std::forward<T>(newName)); } // move rvalues;
} // ...
private:
std::vector<std::string> names;
};
评论中写的是正确的,即使这并不意味着这两种解决方案是等价的,并且书中确实讨论了一些差异。
然而,在勘误表中,作者评论了书中未讨论的另一个差异:
(1) 左值和右值的重载与 (2) 采用通用引用 (uref) 的模板之间的另一个行为差异是左值重载声明了它的参数
const
,而 uref 方法没有。这意味着在左值重载的参数上调用的函数将始终是const
版本,而在 uref 版本的参数上调用的函数const
只有在传入的参数是 时才是版本const
。换句话说,非const
左值参数可能会在重载设计与 uref 设计中产生不同的行为。
但我不确定我是否理解它。
实际上,写这个问题我可能已经理解了,但我没有写答案,因为我仍然不确定。
可能作者是说,当一个非const
左值被传递给时addName
,在第一个代码中,而在第二个代码中是非-,这意味着如果被传递给另一个函数(或调用了成员函数)该函数需要接受一个参数(或者是一个成员函数)。newName
const
const
newName
const
const
我的解释是否正确?
但是,我看不出这在具体示例中有何不同,因为没有调用成员函数 on newName
,也没有将它传递给具有不同重载的函数(不完全是:const
和非const
参数std::vector<T>::push_back
有两个const T&
参数重载和T&&
arguments`,但左值仍将仅绑定到前一个重载...)。