转换可变参数函数的参数
Convert arguments of variadic function
这可能是一个新手问题,但我认为它可能很有趣。假设我有这个功能:
template <typename First, typename... T>
int ComputeSomething(const First& f, const T&... t);
我想编写第二个函数,在一般情况下调用上面的函数,但在 First
和 T
的类型为 float
时转换参数,即,它在每个参数上调用一个 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)...);
}
我怎样才能做到这一点?
您可以使用助手来测试是否所有类型都是 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)...);
}
助手非常通用,也可以在其他上下文中使用。
编辑:我将 std::tuple
替换为 typelist
,尽管在上述上下文中永远不会实例化元组。我只是为了方便而使用它,但由于有些人认为它的开销太大,所以我编辑了答案。
添加一个透明的 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)...);
}
这可能是一个新手问题,但我认为它可能很有趣。假设我有这个功能:
template <typename First, typename... T>
int ComputeSomething(const First& f, const T&... t);
我想编写第二个函数,在一般情况下调用上面的函数,但在 First
和 T
的类型为 float
时转换参数,即,它在每个参数上调用一个 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)...);
}
我怎样才能做到这一点?
您可以使用助手来测试是否所有类型都是 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)...);
}
助手非常通用,也可以在其他上下文中使用。
编辑:我将 std::tuple
替换为 typelist
,尽管在上述上下文中永远不会实例化元组。我只是为了方便而使用它,但由于有些人认为它的开销太大,所以我编辑了答案。
添加一个透明的 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)...);
}