使用 gcc 9.3 的部分模板专业化失败,之前工作
Failure on partial template specialization with gcc 9.3, was working before
我查了This Whosebug post,还是看不懂
我有这段代码(是的,我知道 <functional>
实现了同样的事情)有效(如果没记错的话,它是 gcc6),现在失败了 gcc9.3.0
鉴于这些 class 定义
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(){}
};
和这些定义
template <typename D,typename P>
struct ParamFunctionType{
typedef void (*value)(D,P);
};
template <typename P>
struct ParamFunctionType<void,P>{
typedef void (*value)(P);
};
我有这些子classes
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); }
};
现在第二个定义对我来说似乎是一个专业化(对于 D 设置为 void),但我得到以下错误
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>{
|
我错了什么?
(Jarod42here提供了一个MVCE)。
如果我没记错的话,这是提交给 here 的 GCC 错误。
它在 GCC 7.1 中引入。
根据@NutCracker提供的this bug filing评论4的推理我修改了代码如下
template <typename P, typename ParamFunctionType<void, P>::value f>
class FunctionParamCallback<void, P, f> : public Callback<void>
{ /*..*/};
这样就避免了f类型可能出现的不一致解析,在gcc9.3中编译时无需通过编译选项放宽检查。
我查了This Whosebug post,还是看不懂
我有这段代码(是的,我知道 <functional>
实现了同样的事情)有效(如果没记错的话,它是 gcc6),现在失败了 gcc9.3.0
鉴于这些 class 定义
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(){}
};
和这些定义
template <typename D,typename P>
struct ParamFunctionType{
typedef void (*value)(D,P);
};
template <typename P>
struct ParamFunctionType<void,P>{
typedef void (*value)(P);
};
我有这些子classes
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); }
};
现在第二个定义对我来说似乎是一个专业化(对于 D 设置为 void),但我得到以下错误
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>{
|
我错了什么?
(Jarod42here提供了一个MVCE)。
如果我没记错的话,这是提交给 here 的 GCC 错误。 它在 GCC 7.1 中引入。
根据@NutCracker提供的this bug filing评论4的推理我修改了代码如下
template <typename P, typename ParamFunctionType<void, P>::value f>
class FunctionParamCallback<void, P, f> : public Callback<void>
{ /*..*/};
这样就避免了f类型可能出现的不一致解析,在gcc9.3中编译时无需通过编译选项放宽检查。