我想在一个文件中定义一个模板函数,并在许多文件中使用。这是否与常规函数原型的工作方式一样?所以我可以定义一次,并将原型包含在其他文件中?我对类有同样的问题,我是否必须在每个头文件中包含模板类的完整定义,就像我为一个类一样?如果我在单独的文件中定义了一个模板函数两次,或者这会被取消选中,会导致错误吗?不同文件中的模板函数和类的使用
还有一个问题,模板函数原型的格式是什么?
我想在一个文件中定义一个模板函数,并在许多文件中使用。这是否与常规函数原型的工作方式一样?所以我可以定义一次,并将原型包含在其他文件中?我对类有同样的问题,我是否必须在每个头文件中包含模板类的完整定义,就像我为一个类一样?如果我在单独的文件中定义了一个模板函数两次,或者这会被取消选中,会导致错误吗?不同文件中的模板函数和类的使用
还有一个问题,模板函数原型的格式是什么?
不,它与普通功能不一样。与常规功能,你可以在头声明
void foo(int);
void foo(double);
,在一些源文件中定义的功能,如foo.cc
,在#包括有使用这些功能的任何源文件的标题,如bar.cc
,并让链接器完成剩下的工作。编译器将编译bar.cc
并生成bar.o
,确信你已经在某处定义了函数,如果你没有,那么你会得到一个链接时错误。
但是如果你使用模板:
template <typename T>
void foo(T) ...
试着想象,将如何工作。源文件foo.cc
和bar.cc
是独立的,彼此之间一无所知,只是他们同意他们都包括头文件中包含的内容(这是整个想法)。所以bar.cc
不知道如何foo.cc
实现的东西,而foo.cc
不知道bar.cc
将如何处理这些功能。在这种情况下,foo.cc
不知道什么类型的bar.cc
将为T指定。那么foo.cc
怎么可能有太阳下每个类型名称的定义?
它不能,所以这种做法是不允许的。您必须在标题中包含整个模板,以便编译器可以定义为foo(int)
或foo(string)
或foo(myWeirdClass)
或任何bar.cc
要求的定义,并将其构建为bar.o
(或者如果模板对此没有意义类型)。
类也是一样。
这些规则对于模板专业化有点不同,但在尝试高级技术之前,您应该掌握基本知识。
只是为了确定是否我在两个不同的文件中定义它们的方式不同,我们可以说即使这样做是错误的吗?对于实例化模板的文件,每个定义都是本地的吗?为什么我不能定义一个原型,如template
@rubix - 你绝对不允许有不同的定义。通常你可以通过将它放在一个头文件中来解决这个问题,并且在你使用该模板的任何地方都包含它 – 2011-04-25 05:32:06
@rubixibuc:是的,每个定义都适用于可以看到它的源文件。只有当一个消息来源看到时,才会有冲突。编译器可能会允许这样的原型(我不知道为什么),但是如果您尝试使用该函数而不提供调用源可以看到它的定义,那么编译器将会抱怨(如果没有,请让我知道)。 – Beta 2011-04-25 05:34:54
看到这个FAQ。特别是,items 12, 13 and 14涉及分离模板函数的声明和定义。
http://stackoverflow.com/questions/3368883/how-does-this-size-of-array-template-function-work显示一个模板原型的例子,其中定义实际上并不需要在这一天,链接器不会抱怨。 – QuentinUK 2016-02-28 11:22:53