【问题标题】:GCC: Function wrapper template troublesGCC:函数包装模板的麻烦
【发布时间】:2016-10-06 13:59:35
【问题描述】:

我在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 ...)' 不是模板非类型参数的有效类型 结构函数包装器 ^ prog.cpp:在函数'int main()'中: prog.cpp:20:45: 错误:'int(int, int)' 不是模板非类型参数的有效类型 FunctionWrapper 包装器;

关于如何在clanggcc 上进行这项工作的任何想法?

谢谢!

【问题讨论】:

  • 即使在 g++6.1 中也不起作用
  • 我认为,与其直接使用Ret(Args...),不如在尝试对函数指针类型进行任何复杂操作时使用 typedef 可能会取得更大的成功。在匹配模板模式时,编译器似乎对协调函数与函数指针转换感到困惑。例如。 template &lt;class Ret, class... Args&gt; using free_function = Ret(*)(Args...);

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


【解决方案1】:

我认为这是一个 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>
{ };

但我不认为这是必要的。

【讨论】:

  • Having Ret(Args...) as a template non-type parameter... 应该是Having Ret(Args...) as a template type parameter... ?
  • @Arunmu 不,非类型。
  • 是的,gcc 过早地执行 [temp.param] 调整。示例(改编自 temp.param):godbolt.org/g/TTXCoU
猜你喜欢
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多