Rejeição de especialização parcial com function como argumento de modelo

Obteve este código que costumava compilar bem com a versão anterior do gcc:

template  struct HelperWrapper; // [...] template  struct HelperWrapper { static inline int WrapFuncT(const int) { return 0; // Changed } }; // Unary template  struct HelperWrapper { static inline int WrapFuncT(const int) { return 1; // Changed } }; // Binary template  struct HelperWrapper { static inline int WrapFuncT(const int) { return 2; // Changed } }; 

É rejeitado pelo GCC 7.1.1 com erro:

 a.hpp:683:16: error: partial specialization 'struct Type::Implementation::HelperWrapper' is not more specialized than [-fpermissive] struct HelperWrapper ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ a.hpp:640:16: note: primary template 'template struct Type::Implementation::HelperWrapper' struct HelperWrapper; ^~~~~~~~~~~~~ a.hpp:695:16: error: partial specialization 'struct Type::Implementation::HelperWrapper' is not more specialized than [-fpermissive] struct HelperWrapper ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ a.hpp:640:16: note: primary template 'template struct Type::Implementation::HelperWrapper' struct HelperWrapper; ^~~~~~~~~~~~~ a.hpp:707:16: error: partial specialization 'struct Type::Implementation::HelperWrapper' is not more specialized than [-fpermissive] struct HelperWrapper ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ a.hpp:640:16: note: primary template 'template struct Type::Implementation::HelperWrapper' struct HelperWrapper; 

Eu não entendo a mensagem, já que o que o GCC diz como o template principal é, no meu entender, uma declaração direta de uma estrutura de template genérica que não existe em nenhum lugar no código.

A ideia deste código é capturar a assinatura e o tipo de argumento da function passada.

1) O GCC está certo? (Se você acha que não é, por favor cite o que apóia o seu pedido no padrão atual)

2) Como eu corrijo o código para que seja aceito pelo GCC (é aceito com o Clang no VisualStudio 2003). Eu não posso usar o C ++ 11.

Edit: Eu finalmente consegui reportar isso aos desenvolvedores do GCC e é um bug que deve ser corrigido nas próximas versões.

Parece um bug do compilador, mas não encontrou nenhuma referência a este problema no Bugzilla do GCC . No entanto, eu testei seu código com os compiladores GCC recentes no Compiler Explorer como você fez e usando pointers de function em vez de referências de function funciona com o GCC 7.1 também. Aqui está uma demonstração ao vivo .


O compilador pode reclamar se a especialização de modelo parcial não for mais especializada que o modelo principal. Mas, neste caso, o GCC está errado porque você especializou o parâmetro do modelo FuncSig como uma referência de function ( Ret (&)() ). O fato mais estranho é que o compilador não reclama de pointers de function.

Além disso, a causa do problema parece que não o FuncSig mas o parâmetro do modelo f . Quando removi o f do modelo principal e de suas especializações, o problema desapareceu:

 template  struct HelperWrapper; template  struct HelperWrapper { static inline int WrapFuncT(const int) { return 0; } }; /* ... */ 

Veja a demonstração ao vivo aqui .