简体   繁体   English

C ++完美转发

[英]C++ Perfect Forwarding

1) 1)

template<typename T, typename Arg> 
  shared_ptr<T> factory(Arg arg)
  { 
    return shared_ptr<T>(new T(arg));
  } 

2) 2)

template<typename T, typename Arg> 
  shared_ptr<T> factory(Arg& arg)
  { 
    return shared_ptr<T>(new T(arg));
  } 

3) 3)

template<typename T, typename Arg> 
  shared_ptr<T> factory(Arg const & arg)
  { 
    return shared_ptr<T>(new T(arg));
  } 

*)Why is number 3 is preferred than number 1 and number 2? *)为什么3号比1号和2号更受欢迎?

*)if factory(41) is called, why is called on rvalue? *)如果调用工厂(41),为什么要调用右值?

*)# define BOOST_ASIO_MOVE_ARG(type) type&&. *)#define BOOST_ASIO_MOVE_ARG(type)type &&。 what's && in this case? 在这种情况下什么是&&?

Actually, approach #3 is not better than 1 and 2. It all depends on T 's constructor(s). 实际上,方法#3 并不比1和2好。这完全取决于T的构造函数。

A somewhat standard way to do this is using rvalue references, which are the && you mention. 一种有点标准的方法是使用右值引用,这是你提到的&&

So, a better factory would be something like this: (which is what perfect forwarding actually is) 所以,一个更好的工厂将是这样的:(这实际上是完美的转发

template<typename T, typename Arg> 
std::shared_ptr<T> factory(Arg && arg)
{
    return std::shared_ptr<T>(new T (std::forward<Arg>(arg)));
}

Due to reference collapsing rules of C++, this function can take (and forward) both rvalue refences and lvalue references, ie, if you pass it an rvalue, it will forward that rvalue faithfully to T 's constructor, and if you give it an lvalue, the two kinds of reference ( Something & && arg ) will collapse and the lvalue reference will be forwarded to the underlying constructor. 由于参考 C ++的折叠规则,这个函数可以接受(并转发)rvalue refences和lvalue引用,也就是说,如果你传递一个rvalue,它会忠实地将rvalue转发给T的构造函数,如果你给它一个左值,两种引用( Something & && arg )将崩溃,左值引用将被转发到底层构造函数。

I think I covered your questions here, but to answer explicitly, 我想我在这里介绍了你的问题,但要明确回答,

  • #3 is not the preferred method here. #3 不是这里的首选方法。 Even before C++11, you probably wanted both const& and & overloads of the factory function. 即使在C ++ 11之前,您可能也想要factory函数的const&&重载。 The const& version is nicer and it will actually accept temporary values, but if your underlying T type has a constructor that accepts a non-const ref, then you would get a compile error because a const& is not implicitly casted to a & . const&版本更好,它实际上会接受临时值,但如果你的底层T类型有一个接受非const ref的构造函数,那么你会得到一个编译错误,因为const&不会隐式地转换为&
  • Because you can't take the address of the literal 41 (this is not 100% technically correct, but I think it's OK to think of lvalues and rvalues this way.) 因为你不能取字面41的地址(这在技术上不是100%正确,但我认为用这种方式考虑左值和右值是可以的。)
  • It signifies an rvalue reference . 它表示rvalue reference You need to read about that; 你需要阅读这个; an explanation will not fit here, and there are already several great ones just a Google search away! 一个解释不适合这里,已经有几个伟大的只是谷歌搜索!

UPDATE : As mentioned tangentially in the comments, using make_shared can be better than constructing a shared_ptr with a just- new ed pointer. 更新 :正如在评论中切向提到的那样,使用make_shared可能比使用new ed指针构建shared_ptr更好。 make_shared might achieve better efficiency by allocating the control block (which includes the reference count) along with the object itself, which would provide better cache locality when accessing the reference counter and the object, and also may save one memory allocation. make_shared可以通过分配控制块(包括引用计数)以及对象本身来实现更高的效率,这将在访问引用计数器和对象时提供更好的缓存局部性,并且还可以节省一个内存分配。 Even if the implementation has none of the optimizations, it won't be any worse than the above version. 即使实现没有优化,也不会比上面的版本差。 So use std::make_shared whenever possible! 所以尽可能使用std::make_shared And this would be how you do it here: 这就是你在这里做的方式:

template<typename T, typename Arg> 
std::shared_ptr<T> factory (Arg && arg)
{
    return std::make_shared<T>(std::forward<Arg>(arg));
}

*)Why is number 3 is preferred than number 1 and number 2? *)为什么3号比1号和2号更受欢迎?

(1) won't work if Arg is non-copyable. (1)如果Arg不可复制,则不起作用。 (2) won't allow you to pass an rvalue, as in factory<int>(42); (2)不允许你传递右值,如factory<int>(42);

Note that none of the three examples involve perfect forwarding. 请注意,这三个示例都不涉及完美转发。 I'm not sure what the subject of your question refers to. 我不确定你问题的主题是什么。

*)if factory(41) is called, why is called on rvalue? *)如果调用工厂(41),为什么要调用右值?

I'm not sure I understand the question. 我不确定我理解这个问题。 41 is an rvalue by definition. 41是根据定义的右值。

*)# define BOOST_ASIO_MOVE_ARG(type) type&&. *)#define BOOST_ASIO_MOVE_ARG(type)type &&。 what's && in this case? 在这种情况下什么是&&?

type&& is an rvalue reference to type . type&&是对type右值引用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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