【问题标题】:Perfect forwarding variadic template with pass by value for selected types完美的转发可变参数模板,为选定类型传递值
【发布时间】:2017-10-13 06:04:28
【问题描述】:

提到 herethere 有时最好按值传递而不是按引用传递。

鉴于此,是否可以结合完美的转发可变参数模板选择某些类型进行值传递?

template<typename... Args>
void foo(Args&&...);  // passes everything by reference

template<typename... Args>
void foo(Args...);  // passes everything by value

template<typename... Args>
void foo(std::conditional_t<is_selected_v<Args>, Args, Args&&>...); // won't deduce types

template<typename... Args>
void foo(...);  // this is wrong :)

注意不能推断类型意味着它不适用于构造函数

【问题讨论】:

  • 嗯,我认为当内联是可能的/可能时,几乎总是使用完美的转发函数,这使得传递值的需要远不那么明显......
  • 如果满足某些条件,您是要按值传递所有参数,还是要按值传递一些参数和通过引用传递一些参数?后者似乎不可能......
  • @Knoep 后者。我想不出任何可以做到这一点的东西,因此提出了这个问题
  • @MassimilianoJanes 我不知道优化器是如何工作的,但我猜大型函数不会经常被内联。或重度递归函数
  • 如果函数是“大”的,那么链接中提到的按值传递的理由不适用。请注意,如果在合理的情况下没有内联(和优化)完美的转发函数,那么大多数基于它的模板魔法在实践中将毫无用处......

标签: c++ templates perfect-forwarding


【解决方案1】:

我认为我们能做的最好的就是

template<typename T>
using pass_policy_t = std::conditional_t<
  std::is_scalar<std::decay_t<T>>::value,
    std::decay_t<T>,
    T&&>;

template<typename... Args>
void foo_impl( pass_policy_t<Args>... );

template<typename... Args>
inline void foo( Args&&... args )
{
  foo_impl<Args...>( std::forward<Args>(args)... );
}

其中 pass_policy_t 计算实际的传递类型(在上面的示例中,标量类型衰减)。当然,不能保证 foo 会被优化,无论如何我很高兴看到它不会被优化的合理情况...... :) 这是一个 live snippet 尝试......

为了完整起见,有一个关于该问题的标准提案(n3445)但它似乎无处可去......无论如何,1)它支持怀疑,如果没有更多的语言支持,目前是不可能的,2)它显示即使在完全由程序员控制的情况下通过值传递策略,如果没有像 is_fast_pass 内在特征这样的东西,它也不会是最优的......

【讨论】:

  • 这是个好主意!您是否进行了一些测试,证明它在大多数情况下实际上都有效?
  • @Knoep 我为测试添加了具体的通过策略;据我所知,基本测试是内联的......
  • 是的,尝试使用is_empty 和自定义复制构造函数。应该复制的东西会被复制。
猜你喜欢
  • 1970-01-01
  • 2013-01-06
  • 2011-09-23
  • 2016-03-22
  • 2017-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多