简体   繁体   中英

Failure on partial template specialization with gcc 9.3, was working before

I checked This stackoverflow post , but I still cannot understand.

I have this code (yes I know <functional> achieves the same thing) which worked (if memory serves me right, it was gcc6) and now fails with gcc9.3.0

Given these class definitions

template <typename D>
class Callback{
public:
  virtual void operator()(D d)=0;
  virtual ~Callback(){}
};

template <>
class Callback <void>{
public:
  virtual void operator()()=0;
  virtual ~Callback(){}
};

and these definitions

template <typename D,typename P>
struct ParamFunctionType{
  typedef void (*value)(D,P);
};

template <typename P>
struct ParamFunctionType<void,P>{
  typedef void (*value)(P);
};

I have these subclasses

template <typename D, typename P, typename ParamFunctionType<D,P>::value f>
class FunctionParamCallback:public Callback<D>
{
    P p;

    FunctionParamCallback(const P& pp) : p(pp) {}
       
    void operator()(D d) { (*f)(d,p); }
};

template <typename P, void (*f)(P)>
class FunctionParamCallback<void, P, f> : public Callback<void>
{
    P p;

    FunctionParamCallback(const P& pp) : p(pp) {}
    void operator()() { (*f)(p); }
};

Now the second definition seems a specialization to me (for D set to void), but I get the following error

 error: partial specialization ‘class helium::scb::FunctionParamCallback<void, P, f>’ is not more specialized than [-fpermissive]
  297 |     template <typename P,void (*f)(P)> class FunctionParamCallback<void,P,f>:public Callback<void>{
      |                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../helium/signal/callback.h:284:85: note: primary template ‘template<class D, class P, typename helium::scb::ParamFunctionType<D, P>::value f> class helium::scb::FunctionParamCallback’
  284 |     template <typename D,typename P,typename ParamFunctionType<D,P>::value f> class FunctionParamCallback:public Callback<D>{
  |                                                  

What am I mistaking?

(a MVCE is provided by Jarod42 here ).

This is a GCC bug filed here if I am not mistaken. It is introduced in GCC 7.1.

Following the reasoning of comment 4 of this bug filing provided by @NutCracker I modified the code as follows

template <typename P, typename ParamFunctionType<void, P>::value f>
class FunctionParamCallback<void, P, f> : public Callback<void>
{ /*..*/};

This prevents the possibly inconsistent resolution for the type of f, and compiles in gcc9.3 without need to relax the checks through compilation options.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM