C ++模板 - 几个特化 - 是行为定义的吗?

时间:2018-02-13 16:15:11

标签: c++ templates template-specialization

让我们想象一下,我宣布了一个模板结构:

template <int N> struct mystruct;

让我们假设我的结构对所有N都有一般行为,除非N == 0

我可以声明N == 0的特殊行为:

template<> struct mystruct<0> {int k = 0};

我还可以用以下方式声明一般行为:

template<int N> struct mystruct {float k = 3.14;};

如果我在主要地方跑:

struct mystruct<-1> x;
struct mystruct<0> y;
struct mystruct<1> z;
std::cout << x.k << " " << y.k << " " << z.k << std::endl;

我得到了我想要的东西:3.14 0 3.14,无论模板声明的顺序如何。

但是我想知道这种行为是否有保险。的确,当我宣布:

struct mystruct<0> y;

在我看来,这也可以由mystruct实现来定义。

所以问题是:

C ++规范化是否确保模板特化<0>覆盖通用基本实现<int N>,无论代码中的模板特化顺序是什么?

2 个答案:

答案 0 :(得分:5)

对于您的特定情况,因为专门化出现在主模板之后,并且假设它们两个出现,那么是。否则,如果一个TU看到专业化,但是另一个TU看不到它们并且它们都使用mystruct<0>,那么您将获得未定义的行为。

在一般情况下,由于许多专业化可能相当复杂,C ++标准在[temp.expl.spec]/7有这样的说法,强调我的:

  

为函数放置显式特化声明   模板,类模板,变量模板,成员函数   类模板,类模板的静态数据成员,成员   类模板类,类模板的成员枚举,   类模板的成员类模板,成员函数模板   类模板,类模板的静态数据成员模板,   类模板的成员模板的成员函数,成员   非模板类的成员模板的功能,静态数据   非模板类的成员模板,成员函数模板   类模板的成员类等,以及部分的放置   类模板的特化声明,变量模板,   非模板类的成员类模板,静态数据成员   非模板类的模板,类的成员类模板   模板等可以影响程序是否格式正确   到显式专业化的相对定位   声明及其在翻译单元中的实例化要点   如上下文所述。 撰写专业时,请   小心它的位置;或者使它编译将是这样的试验   点燃自焚。

答案 1 :(得分:3)

  

C ++规范化是否确保模板特化<0>覆盖一般构造<N>,无论代码中的模板特化顺序是什么?

只是澄清术语,

template<int N> struct mystruct {float k = 3.14;};

不是专业化。它是主要/通用/基础实现。

只要在使用mystruct<0>点处可见专业化,只要使用mystruct<0>,就会使用专精mystruct<0>。这就是专业化的全部要点。