我一直在使用新的c ++标准中的可变参数模板,并提出了一个map函数(header +使用了decs除外):
template<typename T>
T square(T i)
{
return i * i;
}
template <typename T, typename... Ts>
const tuple<Ts...> map(const T f, const Ts...args)
{
return make_tuple(f(args)...);
}
int main(int c, char *argv[])
{
tuple<int, int> t;
int (*fp) (int) = square;
t = map(fp, 6, 8);
cout <<get<0>(t) <<endl;
cout <<get<1>(t) <<endl;
return 0;
}
哪个有效。只要所有参数都是map的相同类型。如果我更改主要使用稍微更一般的形式:
tuple<int, float> t;
t = map(square, 6, 8.0f);
gcc 4.4报告:
In function ‘int main(int, char**)’:
error: no matching function for call to ‘map(<unresolved overloaded function type>, int, float)’
任何想法如何使这项工作?
答案 0 :(得分:5)
首先,您不能将未解析的函数模板作为指针(或模板参数)传递,您只能传递它的实例。这意味着您的模板的第一个参数在此示例中作为int (*)(int)
传递,并且无法调用float (*)(float)
实例化。我不确定解决这个问题的最佳方法,但无论如何,从技术上来说,你所询问的并不是这样。
我没有编译器来测试它,但我认为如果你使用std::function
推断你传入的函数所需的类型,你可能能够将参数转换为函数。像这样:
template<typename T, typename Ts...>
tuple<Ts...> map(std::function<T (T)> const &f, Ts... args) {
return make_tuple(static_cast<Ts>(f(static_cast<T>(args)))...);
}
请参阅,我认为您需要为该函数强制转换参数(作为T
)和返回类型(作为Ts
),因为看起来某些隐式转换规则不起作用这个模板。
如果我的语法不起作用(可能没有,...
在你没有编译器的时候很棘手),你可能会把它重写为很多更详细的函数,它在调用函数之前解包每个Ts
,然后在它去的时候构建一个元组。我不确定这是否真的有必要,但我的感觉是编译器对所有...
解包的支持现在有点不稳定,所以即使你想出一些应该有用的东西,我也不会如果您的编译器无法处理它,我会感到惊讶。