C++ 在C+中绕过Dll中的模板问题+;?

C++ 在C+中绕过Dll中的模板问题+;?,c++,templates,dll,game-engine,undefined-symbol,C++,Templates,Dll,Game Engine,Undefined Symbol,背景: 我目前在VisualStudio中构建了一个游戏引擎项目,以便将我的“引擎”编译成dll,供另一个项目“游戏”使用。我的想法是,我可以交换出不同的游戏项目,仍然使用相同的引擎dll代码。在我的引擎代码中,我正在创建我自己的框架,所有其他引擎代码都将使用它。这将有助于将我的实现与代码的其余部分分开,并在需要时使修改更容易 由于我所有的框架代码都可以在dll本身中使用,而不是在“游戏”中使用,我想我可以实现模板。但是,每当我尝试使用引擎框架实现模板时,仍然会收到“undefined symb

背景:

我目前在VisualStudio中构建了一个游戏引擎项目,以便将我的“引擎”编译成dll,供另一个项目“游戏”使用。我的想法是,我可以交换出不同的游戏项目,仍然使用相同的引擎dll代码。在我的引擎代码中,我正在创建我自己的框架,所有其他引擎代码都将使用它。这将有助于将我的实现与代码的其余部分分开,并在需要时使修改更容易

由于我所有的框架代码都可以在dll本身中使用,而不是在“游戏”中使用,我想我可以实现模板。但是,每当我尝试使用引擎框架实现模板时,仍然会收到“undefined symbol”错误

问题:

有没有一种方法可以绕过我的dll中链接器中模板的“未定义符号”错误,而不必知道我的模板将使用的每种类型(例如
类模板MyClass
类模板MyClass
,等等)?如果没有,有没有关于我可以用不同的方式实现我的引擎和不同的游戏项目以保持灵活性的建议?谢谢你的意见


另外,我不想显式定义一个模板类可以使用的所有类型,因为如果我想创建一个向量模板类(比如我自己的向量模板类),它会变得相当大(因为我必须定义很多不同的类)

模板应该是内联代码。他们的代码是在编译器遇到使用模板时在代码生成步骤中创建的,带有该用例的代码。一般来说,试图强迫编译器基于模板创建类是一种谬误、性能问题和不便,这与使用模板的目的背道而驰

一般来说,您需要声明专用模板的对象(变量)以强制编译器生成一个,如果专用变量的数量有限,则需要声明所有变量。即使在这种情况下,编译器也尽量避免创建新函数,除非它们是虚拟函数


大多数模板库在头文件中完全声明方法代码,并且可能根本没有二进制对象文件。就像mock_blatt在评论中所说的那样,在头文件中声明模板,在从头文件使用的include文件中实现方法和好友

模板应该是内联代码。他们的代码是在编译器遇到使用模板时在代码生成步骤中创建的,带有该用例的代码。一般来说,试图强迫编译器基于模板创建类是一种谬误、性能问题和不便,这与使用模板的目的背道而驰

一般来说,您需要声明专用模板的对象(变量)以强制编译器生成一个,如果专用变量的数量有限,则需要声明所有变量。即使在这种情况下,编译器也尽量避免创建新函数,除非它们是虚拟函数

大多数模板库在头文件中完全声明方法代码,并且可能根本没有二进制对象文件。就像mock_blatt在评论中所说的那样,在头文件中声明模板,在从头文件使用的include文件中实现方法和好友

“我不想显式定义模板类可以使用的所有类型,因为这样会变得相当大”

您希望DLL包含什么内容?它要么包含
MyClass
,要么不包含。编译器会实例化
MyClass
,对于它知道的每一种类型,你的DLL都是巨大的

“我不想显式定义模板类可以使用的所有类型,因为这样会变得相当大”


您希望DLL包含什么内容?它要么包含
MyClass
,要么不包含。编译器会实例化
MyClass
,对于它知道的每一种类型,你的DLL都是巨大的

模板插入是在编译时生成的,因此如果不想单独声明所有可能的实例化,则必须将所有模板定义移动到头文件中

一种常见的方法是,每个类都将所有模板定义放在一个内联文件中,例如
.inl
.cxx
文件,然后将该内联文件包含在相应头文件的末尾

例如,对于具有单个模板函数的类
Foo

Foo.hpp的内容

class Foo
{
    template <typename T>
    void bar();
};

#include "Foo.inl" // Include template definitions

这样,只要将
Foo::bar
与新的
T
一起使用,就会生成一个新的模板实例化。

在编译时生成模板实例化,因此,如果您不想单独声明所有可能的实例化,那么必须将所有模板定义移动到头文件中

一种常见的方法是,每个类都将所有模板定义放在一个内联文件中,例如
.inl
.cxx
文件,然后将该内联文件包含在相应头文件的末尾

例如,对于具有单个模板函数的类
Foo

Foo.hpp的内容

class Foo
{
    template <typename T>
    void bar();
};

#include "Foo.inl" // Include template definitions

这样,只要将
Foo::bar
与一个新的
T
一起使用,就会生成一个新的模板实例化。

我认为显式导出模板实例化是将所有代码都放在头文件中的一种变通方法。一种更简洁的方法(例如,由SFML使用)是让模板头只包含声明,然后在底部包含定义实现的.inl文件之类的内容。然后,所有内容都包含在include文件中,但是头文件本身对于用户来说是干净的。我相信显式导出模板的实例化是将所有代码都包含在头文件中的解决办法。一种更干净的方法(例如,由SFML使用)是使用模板