是否可以添加类模板专业化并影响该类的先前用法?

问题描述

我有一些带有声明的模板类和模板函数的头文件

print.h:

template<typename T> struct Printer {
  static void print();
};

template<typename T> void print();

在实现文件中,我有Printer的一些基本实现,其某些专业化以及调用print函数Printer<T>::print的实现。

print.cpp

template<typename T> void Printer<T>::print() {
  cout << "base";
}

template<> struct Printer<int> {
  static void print() {
    cout << "int";
  }
};

template<> struct Printer<bool> {
  static void print() {
    cout << "bool";
  }
};

template<typename T> void print() {
  return Printer<T>::print();
}

在另一个文件中,我添加Printer的另一个特殊化,并在其后调用函数print

another.cpp

template<> struct Printer<char> {
  static void print() {
    cout << "char";
  }
};

void printChar() {
  print<char>();
}

Printer<T>::print叫哪个printChar?基础或专业Printer<char>?我可以通过这种方式更改printChar的行为吗?

(首先编译print.cpp)


我将此代码以相同的顺序编译到单个文件中,并称为printChar输出为“ char”。但是我不确定它是否可以像我描述的那样在不同文件中工作。因为对我来说,它看起来像通过作弊注入打开了扩展现有代码的能力。但是,也许可以练习(Swift基于类似的扩展名)。如果可行,可以练习吗?

解决方法

我不确定您指的是以前的用法。在print<char>专业化之后,我只看到print<char>的一种用法。

模板的工作方式类似于#define,它们根据需要按需标记出定义。因此,在需要删除代码时最好使用正确的模板专业化定义,这顺便每个TU独立进行。而且这些定义在TU之间必须相同。

请参见[temp.expl.spec]/pp.6-7

6 如果模板,成员模板或类模板的成员是显式专门化的,则应在首次使用该专门化之前声明该专门化,这将导致发生隐式实例化,在发生这种使用的每个翻译单位中;无需诊断。

7 显式专业化声明的位置...会根据指定的显式专业化声明的相对位置及其在翻译单元中的实例化点,影响程序是否格式正确上面和下面。编写专长时,请注意其位置;或将其编译将是一种点燃其自焚的试验。

只要在使用print<char> 的每个翻译单元中将print<char> 特化(包括隐式实例化)后,将它们实例化,程序很好。 printChar()情况很好。但是,如果print<char>恰好在任何其他TU中实例化,该程序将成为格式错误的NDR。

由于这个原因,所有专业通常都捆绑(包含)在声明主模板的同一 header 文件中。它可能会增加编译时间,但可以在以后的程序开发和维护中省去很多麻烦。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...