0

这些是我的文件:

--------[ c.hpp ]--------

#ifndef _C
#define _C

#include<iostream>
class C
{
public:
    template<class CARTYPE> void call(CARTYPE& c);
};

#endif

--------[ c.cpp ]--------

#include "c.hpp"

template<class CARTYPE> void C::call(CARTYPE& c)
{
    //make use of c somewhere here
    std::cout<<"Car"<<std::endl;
}

--------[ v.cpp ]--------

class Merc
{};

--------[ main.cpp ]--------

#include "c.hpp"
#include "v.cpp"
//#include "c.cpp"

int main()
{
    Merc m; 
    C someCar;
    someCar.call(m);

}//main

我可以使用命令 g++ -c main.cpp 和 g++ -c c.cpp 等为所有上述文件生成“.o”文件。但是,当我尝试将“.o”文件与 g++ -o car co main.o vo 链接时,我收到此错误:

main.o: In function `main':
main.cpp:(.text+0x17): undefined reference to `void C::call<Merc>(Merc&)'
collect2: ld returned 1 exit status

当我取消注释 main.cpp 中的 #include "c.cpp" 行时,错误消失了,但我觉得以这种方式包含 cpp 文件可能是不好的做法。我做错了吗?在创建单独的目标文件并链接它们时,是否有更好的方法来满足模板化声明?ps:我在更复杂的类结构中使用模板化函数。此处显示的只是一个小示例,目的是向您展示我所面临的错误类型。

4

3 回答 3

2

我相信这是因为当您编译时,编译器c.cpp不知道它需要为.C::call<Merc>(Merc&)main.cppC::call<T>(T&)C::call<Merc>(Merc&)

模板定义本质上是语义宏,与预处理器的词法宏非常相似,#define它们必须在使用它们的编译单元中可见。

于 2010-10-07T05:24:57.550 回答
1

解决这个问题的一个方法是

一个。从 c.cpp 中删除 '#include "c.hpp"' AND

湾。在 'c.hpp' 的末尾包含 'c.cpp' (奇怪的声音 '#include "c.pp"')

这样,模板定义可用于包含“c.hpp”的每个翻译单元,而无需在每个 .cpp 文件中明确这样做。这被称为“包含模型”

于 2010-10-07T05:27:10.597 回答
0

本质上,您不能在当前 C++ 的单独文件中拥有相关的模板声明和定义。您应该在一个文件中完全定义 C 类。

于 2010-10-07T05:44:52.510 回答