[英]C++ Perfect Forwarding
1)
template<typename T, typename Arg>
shared_ptr<T> factory(Arg arg)
{
return shared_ptr<T>(new T(arg));
}
2)
template<typename T, typename Arg>
shared_ptr<T> factory(Arg& arg)
{
return shared_ptr<T>(new T(arg));
}
3)
template<typename T, typename Arg>
shared_ptr<T> factory(Arg const & arg)
{
return shared_ptr<T>(new T(arg));
}
*)为什么3号比1号和2号更受欢迎?
*)如果调用工厂(41),为什么要调用右值?
*)#define BOOST_ASIO_MOVE_ARG(type)type &&。 在这种情况下什么是&&?
实际上,方法#3 并不比1和2好。这完全取决于T
的构造函数。
一种有点标准的方法是使用右值引用,这是你提到的&&
。
所以,一个更好的工厂将是这样的:(这实际上是完美的转发 )
template<typename T, typename Arg>
std::shared_ptr<T> factory(Arg && arg)
{
return std::shared_ptr<T>(new T (std::forward<Arg>(arg)));
}
由于参考 C ++的折叠规则,这个函数可以接受(并转发)rvalue refences和lvalue引用,也就是说,如果你传递一个rvalue,它会忠实地将rvalue转发给T
的构造函数,如果你给它一个左值,两种引用( Something & && arg
)将崩溃,左值引用将被转发到底层构造函数。
我想我在这里介绍了你的问题,但要明确回答,
factory
函数的const&
和&
重载。 const&
版本更好,它实际上会接受临时值,但如果你的底层T
类型有一个接受非const ref的构造函数,那么你会得到一个编译错误,因为const&
不会隐式地转换为&
。 41
的地址(这在技术上不是100%正确,但我认为用这种方式考虑左值和右值是可以的。) rvalue reference
。 你需要阅读这个; 一个解释不适合这里,已经有几个伟大的只是谷歌搜索! 更新 :正如在评论中切向提到的那样,使用make_shared
可能比使用new
ed指针构建shared_ptr
更好。 make_shared
可以通过分配控制块(包括引用计数)以及对象本身来实现更高的效率,这将在访问引用计数器和对象时提供更好的缓存局部性,并且还可以节省一个内存分配。 即使实现没有优化,也不会比上面的版本差。 所以尽可能使用std::make_shared
! 这就是你在这里做的方式:
template<typename T, typename Arg>
std::shared_ptr<T> factory (Arg && arg)
{
return std::make_shared<T>(std::forward<Arg>(arg));
}
*)为什么3号比1号和2号更受欢迎?
(1)如果Arg
不可复制,则不起作用。 (2)不允许你传递右值,如factory<int>(42);
请注意,这三个示例都不涉及完美转发。 我不确定你问题的主题是什么。
*)如果调用工厂(41),为什么要调用右值?
我不确定我理解这个问题。 41
是根据定义的右值。
*)#define BOOST_ASIO_MOVE_ARG(type)type &&。 在这种情况下什么是&&?
type&&
是对type
的右值引用 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.