gpt4 book ai didi

C++完美转发

转载 作者:太空狗 更新时间:2023-10-29 19:48:46 27 4
gpt4 key购买 nike

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 更受欢迎?

*)如果 factory(41) 被调用,为什么在右值上被调用?

*)#定义 BOOST_ASIO_MOVE_ARG(type) 类型&&。在这种情况下 && 是什么?

最佳答案

实际上,方法 3 并不优于 1 和 2。这完全取决于 T 的构造函数。

执行此操作的一种标准方法是使用 rvalue 引用,即您提到的 &&

所以,一个更好的工厂应该是这样的:(这就是完美转发的实际含义)

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

由于 C++ 的 reference collapsing 规则,此函数可以接受(并转发)右值引用和左值引用,即,如果您将右值传递给它,它会将右值忠实地转发给 T 的构造函数,如果你给它一个左值,两种引用 (Something & && arg) 将崩溃,左值引用将被转发给底层构造函数.

我想我在这里涵盖了您的问题,但要明确回答,

  • #3 不是这里的首选方法。甚至在 C++11 之前,您可能需要 factory 函数的 const&& 重载。 const& 版本更好,它实际上会接受临时值,但是如果您的底层 T 类型有一个接受非常量引用的构造函数,那么您将得到一个编译错误,因为 const& 未隐式转换为 &
  • 因为您不能获取文字 41 的地址(这在技术上不是 100% 正确的,但我认为可以这样考虑左值和右值。)
  • 它表示一个右值引用。您需要阅读相关内容;此处不适合解释,只需在 Google 上搜索一下,已经有几个很棒的解释了!

更新:正如在评论中提到的,使用 make_shared 比使用 just-new 构造一个 shared_ptr 更好ed 指针。 make_shared 可以通过将控制 block (包括引用计数)与对象本身一起分配来实现更高的效率,这将在访问引用计数器和对象时提供更好的缓存局部性,并且还可以节省一个内存分配。即使实现没有任何优化,也不会比上面的版本差。所以尽可能使用 std::make_shared!这就是你在这里做的方式:

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

关于C++完美转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18543717/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com