【问题标题】:How to split a static/template class between header and cpp?如何在 header 和 cpp 之间拆分静态/模板类?
【发布时间】:2019-07-03 10:09:14
【问题描述】:

这是我拥有的静态/模板函数:

template<class T>
static T *createWidget(Vec pos, Module *module, ModuleWidget *moduleWidget, int paramId, float minValue, float maxValue, float defaultValue) {
    T *widget = ParamWidget::create<T>(pos, module, paramId, minValue, maxValue, defaultValue);

    moduleWidget->mRandomModeWidgets[paramId] = widget;

    widget->Module = module;
    widget->ModuleWidget = moduleWidget;

    return widget;
}

但我想将声明放在.h 上,将定义放在.cpp 上。

试过了:

template<class T>
static T *createWidget(Vec pos, Module *module, ModuleWidget *moduleWidget, int paramId, float minValue, float maxValue, float defaultValue);

比:

template<class T>
static T *MyClasss:createWidget(Vec pos, Module *module, ModuleWidget *moduleWidget, int paramId, float minValue, float maxValue, float defaultValue) {
    T *widget = ParamWidget::create<T>(pos, module, paramId, minValue, maxValue, defaultValue);

    moduleWidget->mRandomModeWidgets[paramId] = widget;

    widget->Module = module;
    widget->ModuleWidget = moduleWidget;

    return widget;
}

但它说此处可能未指定存储类

我哪里错了?

【问题讨论】:

  • @YanB。所有定义都是声明。而且,模板也可以前向声明。
  • @eerorika 你说得对,我的意思是没有定义的声明,就像那些有普通函数的声明一样,它可以在与定义不同的文件中。术语...
  • @YanB。这就是前向声明,正如我所说;模板可以前向声明。
  • @YanB。那是错误的。 template&lt;class T&gt; struct X;template&lt;class T&gt; void foo(); 分别是类和函数模板声明。在常见的用法中,在单独的文件中提供声明和定义可能没有意义,但这并不意味着这些概念不存在。您完全可以在.h 中声明并在.cpp 中定义模板,这在与显式模板实例化(以及其他一些特定场景)结合使用时非常实用。

标签: c++ templates compiler-errors static header


【解决方案1】:

但它说这里可能没有指定存储类。

我哪里错了?

静态成员函数(模板与否)只能在类定义中声明为静态的。您试图在类定义之外声明函数静态。 static 关键字在类定义之外有不同的含义。只需将其删除:

template<class T>
T *MyClasss::createWidget(params...) {
^          ^^ alśo note that there must be two colons in the scope resolution operator
 \ no static

还请记住,在任何翻译单元中使用的模板实例必须在定义该模板的翻译单元中实例化。这可以通过在单独的 cpp 文件中显式实例化来实现。

【讨论】:

  • 但我想使用 MyClass::createWidget() 调用该函数,而不使用任何 MyClass 实例...
  • @markzzz 你可以这样做。只需在类定义中声明函数 static。
  • 如果我这样做,一旦我在该类中包含标题(没有方法声明)它就会失败:无法从包含该文件的comp-unit调用该方法(而不是定义)。
  • @markzzz 你必须在类定义中声明所有成员函数。
  • 你是说在头文件中对T *MyClasss::createWidget(params...);做,而在源文件中用静态定义它? :O
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-15
  • 1970-01-01
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多