【发布时间】:2018-11-19 02:06:33
【问题描述】:
我正在尝试指定一个将泛型函数作为参数的函数。函数定义如下:
template <typename TRet, typename... TsArgs>
using Fun = TRet (*)(TsArgs...);
如何指定一个以该泛型函数为参数的泛型函数?我试过这个:
template<typename TRet, typename... TsArgs, Fun<TRet, TsArgs...> F>
TRet wrap(TsArgs... args) {
return F(args...);
}
包装这个函数:
bool foo(int x, double y) {
return x < y;
}
像这样:
Fun<bool, int, double> func = wrap<bool, int, double, foo>;
但是,不幸的是,这并不能编译。 gcc 8.1 有以下错误信息:
<source>:16:35: error: no matches converting function 'wrap' to type 'Fun<bool, int, double>' {aka 'bool (*)(int, double)'}
Fun<bool, int, double> func = wrap<bool, int, double, foo>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
而clang 6出现如下错误:
<source>:16:35: error: address of overloaded function 'wrap' does not match required type 'bool (int, double)'
Fun<bool, int, double> func = wrap<bool, int, double, foo>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
但是,如果我用int, double 替换TsArgs,就像foo() 的签名一样,它编译得很好,让我相信在参数列表中间有这些可变参数模板参数不会按我的预期工作。否则我怎么能实现我的目标?
这是 MCVE:
template <typename TRet, typename... TsArgs>
using Fun = TRet (*)(TsArgs...);
template<typename TRet, typename... TsArgs, Fun<TRet, TsArgs...> F>
TRet wrap(TsArgs... args) {
return F(args...);
}
bool foo(int x, double y) {
return x < y;
}
int main() {
Fun<bool, int, double> func = wrap<bool, int, double, foo>;
return 0;
}
【问题讨论】:
-
你的怀疑是正确的。可变模板参数消耗模板的所有参数,如果没有在函数签名中明确指定,几乎无法推断。你必须找到其他方法来做你想做的事。
-
我能想到的最佳解决方法是展开每个函数参数数量的可变参数。你知道什么更好的吗?
-
template <auto F>可能很有用,但如果您想使用重载函数集的成员作为模板参数,这将变得很痛苦。
标签: c++ c++11 templates variadic-templates template-meta-programming