完美转发可变参数模板,为所选类型传递值

时间:2017-10-13 06:04:28

标签: c++ templates perfect-forwarding

有人提到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 :)

请注意,无法推断类型意味着它不会为构造函数工作

1 个答案:

答案 0 :(得分:2)

我认为我们能做的最好的事情是

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 内在特征这样的东西,它也不会是最优的......