以函数为模板参数的部分专业化拒绝

ry

得到了以前用gcc以前的版本可以很好编译的代码:

template <int line, typename FuncSig, FuncSig f>
struct HelperWrapper;

// [...]

template <int line, typename Ret, Ret (&Func)()>
struct HelperWrapper<line, Ret (&)(), Func>
{
    static inline int WrapFuncT(const int)
    {
        return 0; // Changed
    }
};

// Unary
template <int line, typename Ret, typename Arg1, Ret (&Func)(Arg1)>
struct HelperWrapper<line, Ret (&)(Arg1), Func>
{
    static inline int WrapFuncT(const int)
    {
        return 1; // Changed
    }
};

// Binary
template <int line, typename Ret, typename Arg1, typename Arg2, Ret (&Func)(Arg1, Arg2)>
struct HelperWrapper<line, Ret (&)(Arg1, Arg2), Func>
{
    static inline int WrapFuncT(const int)
    {
        return 2; // Changed
    }
};

被GCC 7.1.1拒绝并出现错误:

a.hpp:683:16: error: partial specialization 'struct Type::Implementation::HelperWrapper<line, Ret (&)(), Func>' is not more specialized than [-fpermissive]
     struct HelperWrapper<line, Ret (&)(void), Func>
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.hpp:640:16: note: primary template 'template<int line, class FuncSig, FuncSig f> struct Type::Implementation::HelperWrapper'
     struct HelperWrapper;
            ^~~~~~~~~~~~~
a.hpp:695:16: error: partial specialization 'struct Type::Implementation::HelperWrapper<line, Ret (&)(Arg1), Func>' is not more specialized than [-fpermissive]
     struct HelperWrapper<line, Ret (&)(Arg1), Func>
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.hpp:640:16: note: primary template 'template<int line, class FuncSig, FuncSig f> struct Type::Implementation::HelperWrapper'
     struct HelperWrapper;
            ^~~~~~~~~~~~~
a.hpp:707:16: error: partial specialization 'struct Type::Implementation::HelperWrapper<line, Ret (&)(Arg1, Arg2), Func>' is not more specialized than [-fpermissive]
     struct HelperWrapper<line, Ret (&)(Arg1, Arg2), Func>
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.hpp:640:16: note: primary template 'template<int line, class FuncSig, FuncSig f> struct Type::Implementation::HelperWrapper'
     struct HelperWrapper;

我不明白该消息,因为据我理解,GCC所说的主要模板是对代码中不存在的通用模板结构的前向声明

这段代码的目的是捕获传入的函数的签名和参数类型。

1)GCC对吗?(如果您认为不是,请引用当前标准中支持您主张的内容)

2)如何修复代码,使其被GCC接受(Clang一直支持Visual Studio 2003)。我不能使用C ++ 11。

编辑:我终于成功地向GCC开发人员报告了此错误,此错误应在下一版本中修复。

似乎是一个编译器错误,但尚未在GCC Bugzilla上找到对此问题的任何引用尽管如此,我还是像您一样Compiler Explorer上使用最新的GCC编译器测试了您的代码,并且使用函数指针代替函数引用也可以在GCC 7.1中使用。这是一个现场演示


如果部分模板专业化不比主模板专业化,编译器可能会抱怨但是在这种情况下,GCC是错误的,因为您将FuncSig模板参数专用为函数引用(Ret (&)())。更奇怪的事实是,编译器不会抱怨函数指针。

此外,该问题的原因似乎不是FuncSig,但f模板参数。当我f从主模板及其专业中删除了时,问题消失了:

template <int line, typename FuncSig>
struct HelperWrapper;

template <int line, typename Ret>
struct HelperWrapper<line, Ret (&)()> {
    static inline int WrapFuncT(const int) {
        return 0;
    }
};

/* ... */

这里观看现场演示

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章