使用以前版本的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下载到VisualStudio 2003中)。我不能使用C ++ 11。
编辑:我终于成功向GCC开发人员报告了此问题,这是一个应该在下一版本中修复的错误。
答案 0 :(得分:1)
这似乎是一个编译器错误但未在GCC Bugzilla找到任何对此问题的引用。尽管如此,我使用Compiler Explorer上的最新GCC编译器测试了您的代码,并且使用函数指针而不是函数引用也适用于GCC 7.1。这是live demo。
如果partial template specialization不比主模板更专业,编译器可能会抱怨。但在这种情况下,GCC是错误的,因为您将operator+(Matrix,DiagonalMatrix)
模板参数专门用作函数引用(FuncSig
)。更奇怪的事实是编译器不会抱怨函数指针。
此外,问题的原因似乎不是Ret (&)()
而是FuncSig
模板参数。当我从主模板及其专业化中删除f
时,问题就消失了:
f
查看实时演示here。