前向声明模板类时"未定义模板的隐式实例化"

ben*_*wad 29 c++ templates clang forward-declaration

我有一些代码,我需要向前声明一个模板类(或者至少,前向声明会让事情变得更容易......).我写了一个我正在解决的问题的简化版本,所以我可以在这里显示它:

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

};
Run Code Online (Sandbox Code Playgroud)

我在注释行中得到的错误是:

Error - implicit instantiation of undefined template 'MyTemplateClass<false>'
Run Code Online (Sandbox Code Playgroud)

我需要在MyTemplateClass的前向声明中包含哪些其他细节?由于错误不是来自下一行,我假设它不是由于该方法未定义的事实.我正在使用的编译器是LLVM/CLang,我正在Mac上编译.

kmi*_*las 74

你忘了#include什么吗?

忘记之后我得到了这个

#include <array>
Run Code Online (Sandbox Code Playgroud)

使用时 std::array

:^)

  • 对我来说是#include &lt;string&gt;我正在努力从gcc转到clang。 (3认同)
  • 对我来说,它是#include &lt;vector&gt;(像我这样的初学者注意) (2认同)

das*_*ght 25

为了声明任何类型,模板的变量,该类型的整个定义必须是可用的.您无法转发声明模板,然后开始使用它,就好像它已定义一样.你所能做的就是根据模板声明一个指向类型对象的指针,如下所示:

MyTemplateClass<false> *myTempPtr;  // No error here
Run Code Online (Sandbox Code Playgroud)

不幸的是(但并非出人意料)这会将错误移至下一行.初始化该指针的问题仍然存在:一旦您尝试调用new MyTemplateClass<false>,您将看到错误.

您需要重新安排代码,以便将模板的定义移到其使用位置之前.这可能有点单调乏味,但没有办法解决它:编译器需要在开始实例化模板并调用其方法的位置拥有整个定义.