前向声明模板类时出现“未定义模板的隐式实例化”错误

60

我有一些代码,其中需要前向声明一个模板类(或者至少,前向声明会让事情变得更容易...)。我写了一个简化版本的代码,以便在这里展示:

template<bool>
class MyTemplateClass;

int main( int argc, char* argv[] )
{
    MyTemplateClass<false> myTemp;  // error here
    myTemp.GetTheValue();
    return 0;
}

template<bool bShouldMult>
class MyTemplateClass
{
    int m_myint;
    float m_myfloat;

public:
    MyTemplateClass() : m_myint(5), m_myfloat(3.0f) {}
    float GetTheValue()
    {
        return m_myint * (bShouldMult ? m_myfloat : 1.0f);
    }   

};

我在被注释的那一行遇到了以下错误:

Error - implicit instantiation of undefined template 'MyTemplateClass<false>'

在前向声明MyTemplateClass时,我需要包含哪些其他细节?由于错误不是来自下一行,我假设问题不是因为该方法未定义。我使用的编译器是LLVM/CLang,并在Mac上编译。

3个回答

158

你是否忘记了包含 #include 的某些内容?

我在忘记做什么后得到了这个提示。

#include <array>

使用 std::array

:^)


11
对我来说,这是#include <string>。我正在从gcc转换到clang。 - JeffCharter
1
是的,关于“string”和其他库的默认包含和嵌套包含,编译器之间存在一些差异。 - kmiklas
2
对我来说,它是 #include <vector>(像我这样的初学者请注意) - Aakash Venkat

41
为了声明任何类型的变量,无论是模板还是非模板,都必须提供该类型的完整定义。您不能仅仅前向声明一个模板,然后开始像其已被定义一样使用它。此时您可以做的只是声明一个基于该模板的对象的指针,就像这样:

为了声明任何类型的变量,无论是模板还是非模板,都必须提供该类型的完整定义。您不能仅仅前向声明一个模板,然后开始像其已被定义一样使用它。此时您可以做的只是声明一个基于该模板的对象的指针,就像这样:

MyTemplateClass<false> *myTempPtr;  // No error here

不幸的是(但并不出乎意料),这会将错误移到下一行。初始化指针的问题仍然存在:一旦你尝试调用 new MyTemplateClass<false>,就会出现错误。

你需要重新排列代码,将模板定义移动到使用它的位置之前。这可能有点繁琐,但没有其他办法:编译器需要在你开始实例化模板并调用其方法的地方拥有整个定义。


1
据我所知,您不能在堆栈中(无论是模板还是非模板)前向声明某个内容,然后再实例化它。
此外,我认为对于模板类的前向定义并没有得到广泛支持。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接