2

我正在阅读一篇文章An Idiot's Guide to C++ Templates - Part 2并来到了声明和实现的分离部分。

现在我有三个文件,其内容如下:

样本.hpp

#ifndef SAMPLE_HPP
#define SAMPLE_HPP

template <typename T>
void displayValue(T tValue);

#include "sample.cpp"

#endif

样本.cpp

#include <iostream>
template <typename T>
void displayValue(T tValue){
  std::cout<<tValue<<std::endl;
}

主文件

#include "sample.hpp"
int main(void) {
  displayValue(20);
  displayValue(3.14);
  return 0;
}

据作者介绍,

您的项目/构建现在不得为编译过程添加 Sample.CPP

但是,当我使用时:

g++ main.cpp sample.cpp -o main

它仍然有效!

我认为在这种情况下,对象sample.o仍将不包含关于模板函数的代码displayValue,并且在main.o对象中,它包含。所以理论上没有错误。但是作者为什么must not说呢?

4

2 回答 2

1

您没有收到任何错误是正常的。因为您的定义和实现被视为一个文件。

更好和通常的 C++ 风格是;

头文件(myClass.h):你不应该包含实现文件(如果有的话,编译器会找到它)。实现(myClass.cpp): #include myClass.h

主程序 (main.cpp) 这也需要#include myClass.h

如果您使用这种通常的样式实现,您只会收到链接错误,因为您不应该分离模板函数/类的定义和实现。

作者可能指的是这个。

于 2013-06-30T06:00:15.633 回答
0

模板是部分定义,因此它们可以被限定为在标头中“部分”实现。在你的情况下,

样本.hpp

#ifndef SAMPLE_HPP
#define SAMPLE_HPP

#include <iostream>
template <typename T>
void displayValue(T tValue){
  std::cout<<tValue<<std::endl;
}
#endif

主文件

#include "sample.hpp"
int main(void) {
  displayValue(20);
  displayValue(3.14);
  return 0;
}

这在任何情况下都可以完美运行,即使您在多个位置添加标题(并且可读性很强)

否则,您仍然可以通过将 sample.cpp 包含到使用该模板的其他 cpp 中来保持您所做的并且“理论上正确”。这是一个多一点的工作。

注意:这不是问题的确切答案,而是绕过包括问题在内的所有内容的方法。

于 2013-06-30T07:22:18.760 回答