c++ - 了解关于 EMC++ 第 41 项的勘误表的评论
问题描述
在 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`,但左值仍将仅绑定到前一个重载...)。
解决方案
在第二种情况下,当将const std::string
左值传递给模板时
template<typename T>
void addName(T&& newName)
{ names.push_back(std::forward<T>(newName)); }
实例化结果如下(我已经删除了std::forward
调用,实际上是无操作)
void addName(const std::string& newName)
{ names.push_back(newName); }
而如果std::string
传递了一个左值,那么结果实例addName
是
void addName(std::string& newName)
{ names.push_back(newName); }
这意味着调用的非const
版本std::vector<>::push_back
。
在第一种情况下,当将std::string
左值传递给 时addName
,将选择第一个重载,而不管const
-ness
void addName(const std::string& newName)
{ names.push_back(newName); }
这意味着在这两种情况下都选择了的const
重载。std::vector<>::push_back
推荐阅读
- java - SeleniumWebdriver = 如何刷新浏览器并等待特定的电子邮件到达没有时间线
- c# - System.Data.OleDb.OleDbException:“找不到可安装的 ISAM。” - MS Access (.accdb) 和 C# (.Net Framework)
- asp.net-core - 如何在 .Net Core 中创建无 Cookie 会话?
- javascript - 赛普拉斯:点击提交按钮(表单)重定向到另一个页面(baseurl)
- oracle - 使用Oracle的子串时有多个Matches?
- c# - 如何在 C# 中使用 OpenXml 在 excel 上完成边框?
- crystal-reports - 下载报告作为 Power Point
- amazon-web-services - 如何增加磁盘空间 GitLab Runner
- java - nextPacket 函数无法读取 pcap 文件 [jnetpcap]
- java - Java jar 不能正确显示 UTF-8 字符