【问题标题】:error: too many arguments for class template in a parameter packed class template错误:参数包装类模板中的类模板的数量太多了
【发布时间】:2021-04-19 17:49:49
【问题描述】:

我创建了一个主模板和两个特化:一个用于 void 类型,另一个是用于不同参数类型的参数包。

后台是一个“连接”引擎,用来连接返回void的成员函数,所以我不需要返回类型,只需要参数类型。 这些类就像包装器一样,提供了一个语法友好的静态函数来创建具体的链接。

所以我的代码如下所示:


  /**
   * CalleeCreator class, primary template
   */
  template <typename T> class CalleeCreator;

  template <typename... TParams>
  class CalleeCreator<TParams...> final
  {
    public:
      template <typename TObject, void(TObject::*Function)(TParams...)>
      constexpr static void create(const char*name, TObject& instance)
      {
        new Callee< void (TObject::*)(TParams...), Function>( name, instance);
      }
  };

  template <>
  class CalleeCreator<void> final
  {
      template <typename TObject, void(TObject::*Function)(void)>
      constexpr static void create(const char* name, TObject& instance)
      {
        new Callee< void (TObject::*)(void), Function>( name, instance);
      }
  }; 

只要我这样称呼:

CalleeCreator<uint8_t, uint16_t>::create<Object,
    &Object::method> ("test", *this);

我收到编译错误:错误:类模板的参数太多

打电话时

CalleeCreator<void>::create<Object,
    &Object::method> ("test", *this);

按预期工作

我不明白的是,我创建了另一个具有返回类型和相同主模板的版本:

  template <typename TReturn, typename... TParams>
  class CalleeCreator<TReturn(TParams...)> final
  {
    public:
      template <typename TObject, TReturn(TObject::*Function)(TParams...)>
      constexpr static void create(ConstCharPtr name, TObject& instance)
      {
          new Callee< TReturn (TObject::*)(TParams...), Function>( name, instance);
      }
  };

  template <typename TReturn>
  class CalleeCreator<TReturn(void)> final
  {
    public:
      template <typename TObject, TReturn(TObject::*Function)(void)>
      constexpr static void create(ConstCharPtr name, TObject& instance)
      {
          new Callee< TReturn (TObject::*)(void), Function>( name, instance);
      }
  };

如果我打电话给他们,一切都很好并且工作正常:

CalleeCreator<void(uint8_t, uint16_t)>::create<Object,
        &Object::method> ("test", *this);

我不明白我在这里做错了什么。

另外,Callee 类可以查看模板和构造函数。


/** Class Callee, primary
 */
template <typename T, T> class Callee;


template <typename TObject, typename... TParams,
          void (TObject::*Function)(TParams...)>
class Callee<void (TObject::*)(TParams...), Function> final
{
  public:
    Callee(const char* name, TObject& instance){}
};

当然,还有一个 Callee 类,其返回类型也适用于其他解决方案。

【问题讨论】:

  • TReturn(TParams...) 是单一类型。 void 是单一类型。 TParams... 是一个类型列表。
  • @ecatmur 这是否意味着没有解决方案?因为类型列表不能是主模板。正如我所见,不可能以相同的方式使用它,或者我需要模板的另一个名称。

标签: c++ templates parameter-pack


【解决方案1】:

您只需要一个主要的可变参数类模板:

template <typename... TParams>
class CalleeCreator final
{
    // ...
};

你不需要偏特化,你也不需要特化R(void) - 这是一个古老的(来自C),在C++中编写一个带0参数的函数类型的方法是用空括号.

【讨论】:

  • 这解决了问题。就这么简单。诀窍是不要创建“原型”主模板,而是像在使用的文件中一样定义 CalleeCreator。谢谢!
猜你喜欢
  • 2016-09-09
  • 2011-09-07
  • 2017-10-10
  • 1970-01-01
  • 2020-04-07
  • 2019-06-08
  • 1970-01-01
  • 2015-11-26
  • 2013-04-12
相关资源
最近更新 更多