GCC:函数包装器模板问题

时间:2016-06-06 20:24:48

标签: c++ templates c++11 gcc clang

我正在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包装器;

有关如何在clanggcc上同时发挥作用的任何想法?

谢谢!

1 个答案:

答案 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>
{ };

但我不相信这应该是必要的。