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.