我正在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)'不是模板非类型参数的有效类型 FunctionWrapper包装器;
有关如何在clang
和gcc
上同时发挥作用的任何想法?
谢谢!
答案 0 :(得分:8)
我认为这是一个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>
{ };
但我不相信这应该是必要的。