【问题标题】:Failure on partial template specialization with gcc 9.3, was working before使用 gcc 9.3 的部分模板专业化失败,之前一直在工作
【发布时间】:2021-04-21 04:07:05
【问题描述】:

我查了This stackoverflow post,还是看不懂。

我有这段代码(是的,我知道<functional> 实现了同样的事情)它有效(如果我没记错的话,它是 gcc6),现在由于 gcc9.3.0 而失败

鉴于这些类定义

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);
};

我有这些子类

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>{
  |                                                  

我错了什么?

(MVCE 由 Jarod42 here 提供)。

【问题讨论】:

  • 我会说 gcc 错误,Demo 在 gcc 中使用 C++17 或更高版本,并且适用于 clang/msvc。
  • @Jarod42 如果我在下面的回答有误,请纠正。谢谢:)
  • @NutCracker:看起来很匹配。
  • @Jarod42 感谢您的 MCVE!我将在原始帖子中添加评论。

标签: c++ c++11 templates gcc partial-specialization


【解决方案1】:

如果我没记错的话,这是提交给here 的 GCC 错误。 它是在 GCC 7.1 中引入的。

【讨论】:

  • 谢谢,评论 4 提供了原因。
【解决方案2】:

根据@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 中编译,无需通过编译选项放松检查。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-12
    相关资源
    最近更新 更多