2017-09-26 128 views
0

如果我有一个在.cpp文件而不是.h文件中定义的方法的模板类,我可以使用显式实例来让编译器避免无法解析的外部。模板显式实例化与前向声明类型一起工作吗?

但它会工作,如果显式实例化是使用前向声明类型声明的?

template <typename T> struct Template 
{ 
    void someFunc(); //defined in the .cpp file 
} 

class A; 

template Template<A>; 

想,如果A终于没有定义,没有使用Template<A>它的工作?

+0

只是不要分割模板并将其全部定义在头文件中。 – NathanOliver

+0

没有使用'A',要求它在这里完整,所以没有问题。 – Quentin

+0

@Quentin:谢谢你的回答。如果此代码是库的一部分,那么模板 :: someFunc()符号将在lib中导出,并且在定义A时不会导致未解析的外部错误? – Michel

回答

1

首先。编译器仅在实例化模板时生成代码(在您的示例中,由于没有实例化,因此不生成代码)。其次,你传递一个类型模板参数。这里编译器将被允许安全地创建一个实例。 在你的例子中,你不会在某处使用这个类型,但是如果你愿意,为了定义一个函数,我的第一句话将再次适用,并且该函数只是在某个地方实例化时生成的。 就在这时,编译器必须具备所有知识才能生成代码。

// Example program 
#include <iostream> 


template <typename T> struct Template 
{ 
    void someFunc(); //defined in the .cpp file 
}; 

class A; 
Template<A> foo; 

但是,如果您创建了一个采用非类型参数的模板。如您所担心的那样,它会失败,因为类型定义不完整。

// Example program 
#include <iostream> 
#include <string> 

class A; 

template <A parm> struct Template 
{ 
    void someFunc() { 
     parm.foo(); 
    } 
}; 

A a; 
using foo = Template<a>; 

这个例子也是一样的。在这里,您将创建一个对象a,当然编译器需要更多地了解类型。这就是它失败的原因。

// Example program 
#include <iostream> 


template <typename T> struct Template 
{ 
    T a; 
}; 

class A; 
Template<A> foo; 

希望这会有所帮助。

+0

我曾经在另一个项目中为新的类型定义这个模板的专门化时,我有(如预期的)一个未解析的外部函数作为函数在体内定义。所以在另一个项目中,我有效地使用了这个模板,但是有一个符号在模板定义的时候不存在,并且在创建lib文件之前不会定义。有了这个前瞻性的诀窍,我不再有那个未解决的外部问题,我想知道为什么。我相信模板函数的主体必须位于cpp中,以便知道大小。 – Michel