【问题标题】:Is it possible to pass a reference to a variadic template function?是否可以传递对可变参数模板函数的引用?
【发布时间】:2013-03-17 10:50:33
【问题描述】:

假设,我有一个使用 CRTP 并提供可变参数模板静态成员函数的基类

template<typename derived_task>
struct task_impl : library::task
{
   /* some useful functionality implemented using CRTP */
   /// static method for spawning a task.
   template<typename... Args>
   static void spawn(Args... args)
   { library::spawn(new task(args...)); }
 };

和派生类

struct my_task : task_impl<my_task>
{
  /* implementation using functionality of task_impl<> */
  my_task(container&c, int i);
};

然后想通过可变参数模板成员使用

container c( /* args for ctor */ );
my_task::spawn(c,0);

这里发生的是spawn() 创建容器的副本,而不是通过引用传递原始容器。有没有办法强制引用?

【问题讨论】:

  • std::ref 应该可以解决这个问题,不是吗?
  • 确实如此。谢谢。 PS。将接受 1 行答案。聚苯乙烯。 10 分钟内(之前不允许 :-(

标签: c++ c++11 pass-by-reference variadic-templates


【解决方案1】:

您可以使用std::ref 包装参数。

这实际上发生得相当频繁,例如在使用带有引用参数的函数创建std::threads 时,或者在使用std::bind 时。

【讨论】:

  • 我真的不会把它称为问题,只是似乎很多人忘记了对于像 std::bind 和许多其他的东西,默认是按值存储的东西。
  • @PlasmaHH 点已采纳,已编辑,因此我不再称其为问题。
  • 在看到乔纳森的回答后,我检查了std::thread,发现它使用了std::forward&lt;&gt;的完美转发。那么,有什么问题呢?
  • @Walter,__bind_simple 做什么?它使用std::decay 并按值复制参数。完美转发用于避免不必要的副本所需的按值副本完成之前,但这些副本是标准要求的。
【解决方案2】:

你有两个选择,要么用 reference_wrapper 包装参数,所以函数调用复制 reference_wrapper 而不是它引用的对象,或者让你的可变参数函数使用完美转发,以便它可以通过引用传递参数:

template<typename... Args>
 static void spawn(Args&&... args)
 { library::spawn(new task(std::forward<Args>(args)...)); }

【讨论】:

  • 完美转发当然比对已经是引用的对象使用std::ref 好得多。事实上,std::thread 也使用了它。我仍在学习所有与可变参数模板一起使用的技术。
  • 感谢您的评论,我通过将可变参数作为右值(或作为参考)使其工作:void spawn(Args...) ==> void spawn(Args&amp;&amp;...)。为什么还要使用完美转发?
猜你喜欢
  • 2017-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多