【问题标题】:Is this considered explicit C++ template class Instantiation? [duplicate]这是否被视为显式 C++ 模板类实例化? [复制]
【发布时间】:2012-02-26 19:40:04
【问题描述】:

可能重复:
Why can templates only be implemented in the header file?
Why should the implementation and the declaration of a template class be in the same header file?

我是某所大学的计算机科学专业的学生,​​我们得到了要为 hw 处理的文件。 而且我不确定这种实例化是如何工作的。

长代码短它看起来像这样。

在 List.h 中

#ifndef _LIST_H_
#define _LIST_H_

#include <iterator>
#include <ostream>

template <class T>
class List

/* implementation below but not relevant to this post */
.
.
.
.

....下面文件的最后几行。

#include "list.cpp"

#include "list_given.cpp"

#endif

并且 List.cpp 不包含 List.h

我不明白在头文件中包含 List.cpp 是如何工作的。

【问题讨论】:

  • 不,这不是“显式模板实例化”。
  • 如果您将文件命名为“List.*”,还应包括“List.*”(首字母大写),而不是“list.*”。这样您我们就可以不仅在 Windows 上构建您的项目。
  • Cpp 看起来很奇怪,我会在这里使用 hpp

标签: c++ templates header-files


【解决方案1】:

#include 只是导致文本替换,没有别的,所以就好像list.cpp 的全部内容在头文件中重复了一样。这与“显式模板实例化”无关。

list.cpp 不包含标头,否则标头会递归地包含自身。

【讨论】:

  • 它与模板实例化有关,但这里没有显式模板实例化。
  • 它不会导致无限递归,因为.h文件中有一个哨兵定义。
  • 那么这和在实现下面写整个list.cpp内容是一样的吗?如果是这样,这是否会被限定为隐式实例化,因为定义和声明在技术上都在同一个头文件中?
  • @wayfare:在您显示的代码部分的任何地方都没有实例化任何内容。
【解决方案2】:

不,这里没有实例化,这只是解决 C++ 模板的完整定义必须在实例化模板的每个翻译单元中可见的问题,并且一些程序员希望保留定义和声明分开。如果这真的值得,是不被普遍接受的。有些人还喜欢为要包含在标头中的实现文件使用不同的文件结尾(例如tccicc)。

它是如何工作的:

// Foo.h
#ifndef FOO_HEADER_INCLUDED
#define FOO_HEADER_INCLUDED
template<T>
struct Foo {
  void bar();
};

#include "Foo.cpp"
#endif // header guard

// Foo.cpp
// NO HEADER GUARD, NEVER INCLUDE DIRECTLY
// actually this could have an include guard and still work
template<typename T>
void Foo<T>::bar() { /* smart code */ }

现在,每个用户(包括Foo.h 的人)还包括 实现文件和我们的模板工作。另一种方法是 只需将定义写在头文件中即可。

【讨论】:

    【解决方案3】:

    啊啊啊!不要包含.cpp 文件!

    对于编写模板类,您通常将大部分(如果不是全部)实现放在.h 文件中,因此您甚至可能不需要list.cpp。我不知道list_given.cpp 是做什么用的,所以我不能告诉你是否需要那个。

    当你创建一个模板类时,它只是告诉编译器如何创建一个类的模板。因此,您需要在使用列表类的任何文件中包含包含模板整个定义的 list.h

    您的示例不符合显式实例化的条件 - 我不知道您为什么在这里需要它。请参阅this question,尤其是接受的答案,例如。

    【讨论】:

    • 当然,但是对于刚刚学习 C++ 的人来说,除非您有充分的理由不学习,否则坚持公认的做法是个好主意。看到一个头文件包含一个源文件看起来很奇怪,让你想知道它们的原因是什么。
    • @pmr:将实现放在一个单独的文件中并#includeing 这是相当普遍的。但是,为该文件添加 .cpp 扩展名是一个糟糕的主意。
    • 如果我们在这里谈论一些非常神秘的事情,我会同意,但这是很常见的事情。
    • @BenVoigt 我在回答中指出人们喜欢选择其他扩展。你当然是对的,除了cpp 之外的其他扩展名更合适,但我从未见过有人同意一个:)
    • @pmr:当然,可以合理使用许多不同的扩展。但不是.C.cpp.cxx.c++,因为这些都对make有意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多