繁体   English   中英

C ++完美转发

[英]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 )将崩溃,左值引用将被转发到底层构造函数。

我想我在这里介绍了你的问题,但要明确回答,

  • #3 不是这里的首选方法。 即使在C ++ 11之前,您可能也想要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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM