转换可变函数的参数

Convert arguments of variadic function

本文关键字:参数 函数 转换      更新时间:2023-10-16

这可能是一个新手问题,但我认为它可能很有趣。假设我有这样一个函数:

template <typename First, typename... T>
int ComputeSomething(const First& f, const T&... t);

我想写第二个函数,它在一般情况下调用上面的函数,但在FirstTfloat类型时转换参数,即在每个参数上调用Convert函数:

long Convert(float f);
template <typename First, typename... T>
int MyFun(const First& f, const T&... t) {
  return ComputeSomething(f, t...);
}
// This is what I would like:
int MyFun(const float& f, const float& t...) {
  return ComputeSomething(Convert(f), Convert(t)...);
}

我怎么才能做到呢?

添加一个透明的Convert重载,这样就可以绕过非浮点数(也就是说,你可以有混合类型的参数):

template <typename First, typename... T>
int ComputeSomething(const First& f, const T&... t);
long Convert(float f);
// Transparent converter
template <typename T>
T&& Convert(T&& t) { return std::forward<T>(t); }
template <typename First, typename... Ts>
int MyFun(const First& f, const Ts&... t)
{
    return ComputeSomething(Convert(f), Convert(t)...);
}

您可以使用帮助器来测试是否所有类型都是float:

#include <type_traits>
template< typename... > struct typelist {};
template< typename T, typename... Ts >
using is_all_same = std::is_same< typelist< T, Ts... >,
                                  typelist< Ts..., T > >;
long Convert(float f);
template <typename First, typename... T>
typename std::enable_if< !is_all_same< float, First, T... >::value, int >::type
MyFun(const First& f, const T&... t) {
  return ComputeSomething(f, t...);
}
template <typename First, typename... T>
typename std::enable_if< is_all_same< float, First, T... >::value, int >::type
MyFun(const First& f, const T&... t) {
  return ComputeSomething(Convert(f), Convert(t)...);
}

这个helper非常通用,也可以在其他上下文中使用。

编辑:我用typelist替换了std::tuple,尽管元组永远不会在上面的上下文中实例化。我只是为了方便使用它,但由于有些人认为它开销太大,所以我编辑了答案。