C++ 前向声明模板类时“未定义模板的隐式实例化”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12797051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:38:02  来源:igfitidea点击:

"Implicit instantiation of undefined template" when forward declaring template class

c++templatesclangforward-declaration

提问by benwad

I've got some code in which I need to forward-declare the a template class (or at least, forward-declaring would make things a lot easier for me...). I've written a simplified version of the problem I'm having so I can display it here:

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

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

};

The error I'm getting at the commented line is:

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

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

What other detail do I need to include in a forward declaration of MyTemplateClass? Since the error isn't coming from the next line down I'm assuming it isn't due to the fact that the method is undefined. The compiler I'm using is LLVM/CLang, and I'm compiling on Mac.

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

采纳答案by dasblinkenlight

In order to declare a variable of any type, template or not, the entire definition of that type must be available. You cannot forward-declare a template, and then start using it as if it were defined. All you can do at that point is declaring a pointer to an object of a type based on the template, like this:

为了声明任何类型的变量,模板与否,该类型的整个定义必须可用。你不能预先声明一个模板,然后开始使用它,就像它被定义一样。此时您所能做的就是声明一个指向基于模板的类型对象的指针,如下所示:

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

Unfortunately (but not unexpectedly) this moves the error to the next line. The problem of initializing that pointer remains: once you attempt to invoke new MyTemplateClass<false>, you will see an error.

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

You need to re-arrange your code to move the definition of the template ahead of its place of use. This may be somewhat tedious, but there is no way around it: the compiler needs to have the entire definition at the point where you start instantiating your template and calling its methods.

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

回答by kmiklas

Did you forget to #includesomething?

你忘记了#include什么吗?

I got this after forgetting to

我忘记了之后得到了这个

#include <array>

When using an std::array

当使用一个 std::array

:^)

:^)

回答by Arthur

It is from my understanding that you can not forward declare something and then instantiate it in your stack (template or not).

根据我的理解,您不能转发声明某些内容,然后在您的堆栈中实例化它(模板与否)。

Also I don't think there's a very wide support for forward definition of template class

此外,我不认为对模板类的前向定义有非常广泛的支持