1

(我很抱歉标题凌乱。我很乐意接受改进它的建议。)

我会尽量直截了当。我有以下代码:

文件1.hpp

template <class val_t>
struct MatOps;

文件 2.hpp:

#include "file1.hpp"
template <> struct MatOps<float>{
  static void method1(){
    // Do something
  }
  static void method2(){
    // Do something
  }
  static void method3(){
    // Do something
  }
}

文件 3.hpp:

#include "file1.hpp"
template <> struct MatOps<double>{
  static void method1(){
    // Do something different
  }
  static void method2(){
    // Do something different
  }
  static void method3(){
    // Do something different
  }
}

主文件

#include "file2.hpp"
#include "file3.hpp"

int main(){
  float a,b,c,d;

  MatOps<float>::method1(a,b,...);
  MatOps<float>::method2(c,d,...);

  return 0;
}

问题:

  1. 没有使用显式专业化MatOps<double>。然而,MatOps<double>实际上是实例化的吗?或更粗略地说:包含 file3.hpp 是否占用任何存储空间?
  2. 没有使用MatOps<float>::method3(),但我正在使用类中的其他方法。由于我明确使用MatOps<float>,编译器是否生成代码MatOps<float>::method3()

理由:我被要求遵循 MISRA C++:2003 标准中的一些准则。虽然已经过时,但我被鼓励使用其中合理的任何东西。特别是,有一条规则如下:

头文件应用于声明对象、函数、内联函数、函数模板、typedef、宏、类和类模板,并且不应包含或生成占用存储空间的对象或函数(或函数或对象的片段)的定义。

头文件被认为是通过#include指令包含的任何文件,无论名称或后缀如何。

我的代码被大量模板化,因此我可以根据此规则包含任何文件。当我进行完全专业化时,我的问题就出现了(我只做其中两个:file2.hpp 和 file3.hpp 中列出的那些)。什么完整模板专业化?即使不使用,是否也会为它们生成代码?最终,它们会占用存储空间吗?

4

1 回答 1

1

为了回答您的第一个问题,我从cppreference.com引用以下内容:

类模板本身不是类型、对象或任何其他实体。仅包含模板定义的源文件不会生成任何代码。为了使任何代码出现,必须实例化模板:必须提供模板参数,以便编译器可以生成实际的类(或函数,从函数模板)。

包含file3.hpp不会自行生成代码。

至于第二部分,同样来自同一页面,

当代码在上下文中引用需要完全定义类型的模板时,或者当类型的完整性影响到代码时,并且该特定类型没有被显式实例化时,就会发生隐式实例化。例如,当构造此类型的对象时,而不是构造指向此类型的指针时。

这适用于类模板的成员:除非该成员在程序中使用,否则它不会被实例化,并且不需要定义。

除非您正在对类模板进行显式实例化,否则类模板的各个成员函数将不会被实例化,编译器不会为MatOps<float>::method3().

于 2018-05-14T14:44:25.157 回答