我正在GCC 5.3
尝试让一些函数包装器代码在clang
上正常工作。下面是一个归结的例子:
#include <iostream>
using namespace std;
template<class Sig, Sig F>
struct FunctionWrapper;
template<class Ret, class... Args, Ret (*Func)(Args...)>
struct FunctionWrapper<Ret(Args...), Func>
{
};
static int testFunc(int _a, int _b)
{
return _a + _b;
}
int main() {
FunctionWrapper<int(int, int), testFunc> wrapper;
return 0;
}
我在 gcc 上遇到的错误如下:
prog.cpp:9:46:错误:"Ret(Args ...)"不是模板非类型参数的有效类型 struct FunctionWrapper ^ prog.cpp: 在函数 'int main()' 中: prog.cpp:20:45:错误:"int(int, int)"不是模板非类型参数的有效类型 函数包装器包装器;
关于如何在clang
和gcc
上都做到这一点的任何想法?
谢谢!
我认为这是一个 gcc 错误。根据[temp.param]:
类型为"
T
数组"或函数类型为T
的非类型模板参数被调整为"指向T
的指针"类型。
将Ret(Args...)
作为模板非类型参数等效于将Ret(*)(Args...)
作为模板非类型参数。
请注意,gcc 确实 [正确] 编译了以下示例,该示例与您的原始版本基本相同:
static int testFunc(int _a, int _b)
{
return _a + _b;
}
template <int F(int, int)>
struct Foo { };
int main() {
Foo<testFunc> wrapper;
return 0;
}
<小时 />作为一种解决方法,两个编译器都允许简单地强制非类型参数为指针:
template<class Sig, Sig* F>
struct FunctionWrapper;
template<class Ret, class... Args, Ret (*Func)(Args...)>
struct FunctionWrapper<Ret(Args...), Func>
{ };
但我不认为这应该是必要的。