在Sutter在1:15:26的演讲中,它呈现了如下代码,
class employee{
std::string name_;
public:
template<class String, class=
std::enable_if_t< !std::is_same<std::decay_t<String>, std::string>::value > >
void set_name(String && name)
noexcept(std::isnothrow_assignable<std::string &, String>::value)
{
name_ = std::forward<String>(name);
}
}
Run Code Online (Sandbox Code Playgroud)
我知道std::forward
如果name
是左值,name_
将如何工作,将得到复制构造; 如果name
是右值,name_
将构造移动.但是在幻灯片中它还说Optimized to steal from rvalues (and more)
,还有什么呢?
后来它表明这个代码似乎是所有四个实现中最快的,特别是因为char *
,任何人都有耐心去理解这些代码并解释什么是更优化以及为什么它是最快的,特别是在这种情况下char *
?
bam*_*s53 10
首先,请注意代码中包含一个拼写错误,enable_if
即使删除了拼写错误,约束也不会执行所讨论的内容; 特别是该功能不适用char*
,所以显然它不是最快的char*
.你可以看到我在这里询问的一个问题,以及一个'更正'的完美转发设定器(以及Howard Hinnant对此版本的认可).
template <class String>
auto set_name(String&& name)
-> decltype(name_ = std::forward<String>(name), void()) {
name_ = std::forward<String>(name);
}
Run Code Online (Sandbox Code Playgroud)
用于演示的基准测试是set_name
重复调用employee
,以显示成员string
重用其容量而不是每次迭代都有内存分配的情况.基准测试中显示的高栏和短杆之间的差异是重复使用容量与每次迭代进行分配之间的差异.
校正完美转发器快速使用char*
的原因是因为模板char*
仅用于转发a 的实例化char*
而不是需要构造string
参数以便set_name
使用实际string
对象参数进行调用.因为二传手内的任务是快速的string
工具operator=(char*)
避免,做高效的memcpy到其现有的存储和额外拨款.
所以声称Optimized to steal from rvalues (and more)
是因为完美转发除了转发之外什么都不做.它不仅通过一个右值,如果它得到一个右值,但它也不会转换类型,即优化了"forwardee"实现诸如意义string
的operator=(char*)
获得暴露为好.