[英]Understanding comment from the errata about Item 41 of EMC++
In Item 41, Scott Meyers writes the following two classes:在 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;
};
What's written in the comments is correct, even if it doesn't mean at all that the two solutions are equivalent, and some of the differences are indeed discussed in the book.评论中写的是正确的,即使这并不意味着这两种解决方案是等价的,并且书中确实讨论了一些差异。
In the errata , however, the author comments another difference not discussed in the book:然而,在勘误表中,作者评论了书中未讨论的另一个差异:
Another behavioral difference between (1) overloading for lvalues and rvalues and (2) a template taking a universal reference (uref) is that the lvalue overload declares its parameter
const
, while the uref approach doesn't.(1) 左值和右值的重载与 (2) 采用通用引用 (uref) 的模板之间的另一个行为差异是左值重载声明了它的参数
const
,而 uref 方法没有。 This means that functions invoked on the lvalue overload's parameter will always be theconst
versions, while functions invoked on the uref version's parameter will be theconst
versions only if the argument passed in isconst
.这意味着在左值重载的参数上调用的函数将始终是
const
版本,而在 uref 版本的参数上调用的函数只有在传入的参数是const
时才会是const
版本。 In other words, non-const
lvalue arguments may yield different behavior in the overloading design vis-a-vis the uref design.换句话说,非
const
左值 arguments 可能在重载设计与 uref 设计中产生不同的行为。
But I'm not sure I understand it.但我不确定我是否理解。
Actually, writing this question I've probably understood, but I'm not writing an answer as I'm still not sure.实际上,写这个问题我可能已经理解了,但我没有写答案,因为我仍然不确定。
Probably the author is saying that when a non- const
lvalue is passed to addName
, newName
is const
in the first code, and non- const
in the second code, which means that if newName
was passed to another function (or a member function was called on it), than that function would be required to take a const
parameter (or be a const
member function) .可能作者是说当一个非
const
左值被传递给addName
时, newName
在第一个代码中是const
,而在第二个代码中是非const
,这意味着如果newName
被传递给另一个 function (或成员 function 是调用它),而不是 function 需要采用const
参数(或成为const
成员函数) 。
Have I interpreted correctly?我的解释是否正确?
However, I don't see how this makes a difference in the specific example, since no member function is called on newName
, nor it is passed to a function which has different overloads for (not exactly: const
and non- const
parametersstd::vector<T>::push_back
has two overloads for const T&
arguments and T&&
arguments`, but an lvalue would still bind only to the former overload...).但是,我看不出这在具体示例中有何不同,因为在
newName
上没有调用成员 function ,也没有将其传递给对 (不完全是: const
和非const
参数具有不同重载的 functionstd::vector<T>::push_back
有两个重载const T&
arguments 和T&&
arguments`,但左值仍然只绑定到前一个重载......)。
In the second scenario, when a const std::string
lvalue is passed to the template在第二种情况下,当将
const std::string
左值传递给模板时
template<typename T>
void addName(T&& newName)
{ names.push_back(std::forward<T>(newName)); }
the instantiation results in the following (where I've removed the std::forward
call as it is, in practice, a no-op)实例化结果如下(我已经删除了
std::forward
调用,实际上,它是无操作的)
void addName(const std::string& newName)
{ names.push_back(newName); }
whereas if a std::string
lvalue is passed, then the resulting instance of addName
is而如果传递了一个
std::string
左值,那么addName
的结果实例是
void addName(std::string& newName)
{ names.push_back(newName); }
which means that the non- const
version of std::vector<>::push_back
is called .这意味着调用
std::vector<>::push_back
的非const
版本。
In the first scenario, when a std::string
lvalue is passed to addName
, the first overload is picked regardless of the const
-ness在第一种情况下,当
std::string
左值传递给addName
时,无论const
-ness如何,都会选择第一个重载
void addName(const std::string& newName)
{ names.push_back(newName); }
which means that the const
overload of std::vector<>::push_back
is selected in both cases.这意味着在这两种情况下都选择了
std::vector<>::push_back
的const
重载。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.