【问题标题】:ISO C++ - Is it legal to declare in a template - array or function parameter?ISO C++ - 在模板中声明是否合法 - 数组或函数参数?
【发布时间】:2015-03-24 12:43:16
【问题描述】:

我想知道是否允许这样的模板构造:

template<typename T, T arr[4]>

template<typename T, T func(void)>

最新的 ISO C++ 14 草案第 14.1.4 节中的第一个状态:

如您所见,上面的列表显示了模板参数允许的类型,其中没有像“函数”或“数组”这样的东西。然而,最近在第 14.1.8 节,我们有了这个(即使有引用的例子):

所以问题是 - 编译器是否应该允许这样的构造?或者因为这是一个草稿 - 有人可以将它与原始版本进行比较并说它是否相同?可能有问题。

编辑:我要的是标准纸。它的写法有缺陷吗?

我个人的看法是,在任何情况下都不应该允许这种愚蠢和令人困惑的结构。尤其是在 C++ 模板中。

【问题讨论】:

  • 与 C++11 标准相同。
  • 14.1 (8) 不是问题的答案吗?将类型调整为允许的类型,然后就没有问题了。
  • 否,因为在任何情况下模板参数类型都不应该是“函数”或“数组”之一。 14.1 (4) 保证了这一点。
  • 你为什么认为这是白痴混淆
  • 因为“数组”不是“指针”,而模仿另一种类型绝不是一种想要的行为。关于这个问题我已经谈得差不多了。如果您不了解其中的区别,请阅读它。

标签: c++ templates parameters language-lawyer c++14


【解决方案1】:

非类型模板参数调整的规则与函数参数的规则完全相同,如 C++14/11 [dcl.fct]/5 (C++03 [dcl .fct]/3)。同样,数组和函数类型的函数参数调整规则直接从C(C11 6.7.6.3/7; 8)继承而来。

在语言发展的这个阶段更改规则将导致与现有代码、该语言的先前版本、函数参数规则或如果这些规则也发生更改,与 C 不兼容,而且几乎没有什么好处除了纠正语言的一个小怪癖。

如果你想看到这种用法被弃用,我建议在 gcc 和/或 clang 中添加一个警告,用于模板和/或函数参数数组到指针和函数到指针的转换。这个警告不存在的事实表明大多数程序员不同意你对这个结构的看法。

【讨论】:

  • 因为大多数程序员甚至不知道数组本身就是对象。一个普遍的观点是它们只是指向数组第一个元素的指针。很少有人知道它们可以通过引用或指针传递。否则,我相信他们会分享我的意见。但这里的情况是 C++ 标准中的“缺陷”。你什么都没说。
  • @FISOCPP 我解释了当前行为出现的位置、改变它的障碍以及改变它的一种可能途径。超出此范围的任何内容都是意见问题或题外话。
  • 但是您从未回答过 - 这是 ISO 标准缺陷吗?
  • @FISOCPP:您似乎对大多数程序员的评价很低。虽然“数组是指针”的模因在初学者中似乎很常见,但如果不了解对象模型的实际工作原理,你就无法深入了解该语言,而且我遇到的每个非初学者都对此有相当的工作知识。
  • @FISOCPP:不。调整后,他们有一个允许的类型。第 4 条没有说不能指定数组或函数类型;只是参数不能具有这些类型之一。由于调整,它不会。
【解决方案2】:

我想知道是否允许这样的模板构造

是的,根据您引用的条款。通过第 8 节,类型被调整为第 4 节允许的指针。

编译器是否应该允许这样的构造?

是的,因为标准规定必须这样做。

如果您询问标准是否应该允许这些:是的,因为更改它会破坏现有的有效代码。

或者因为这是一个草稿 - 有人可以将它与原始版本进行比较并说它是否相同?

我没有发布的 C++14 标准,但在 this draft 中是相同的,我相信它比标准更新。 C++11 及更早的标准指定了相同的类型调整。

我个人的看法是,在任何情况下都不应该允许这种愚蠢和令人困惑的结构。

它们在 C 中更有意义,因为这种转换很常见(显然我的意思是对于函数参数,而不是模板参数,因为 C 没有模板)。在 C++ 中,通常可以通过更高级别的抽象(std::array 和函子)来避免混淆,并且只有在知道自己在做什么的情况下才应该使用原始数组和指针。

人们可能会提出反对 C++ 中的转换的论点,因为它们可能会有些令人困惑,并且与在 C 中存在它们相比,它们的可读性优势很少。但这将是高度自以为是的,并且在这里偏离主题。

【讨论】:

  • 现在用于 C++ 模板。 C++ 模板是否曾经是 C 语言的一部分。在这里保持什么兼容性?我真的很困惑。
  • @FISOCPP:我提到 C 是因为这是这些类型调整最初的来源,并扩展到模板参数以与函数参数保持一致。很抱歉,如果那个轻微的题外话引起了混乱。与 30 多年的现有 C++ 代码兼容,假设这些调整。
  • Nitpick:我不会称它们为“第 8 条”或“第 4 条”。它们是段落编号。实际的第 8 条是关于声明符的;第 4 条,标准转换。
  • @T.C.:抱歉,当涉及到核心语言律师术语时,我有时会有点不知所措。我只是一个懂工具的程序员。
猜你喜欢
  • 2021-12-21
  • 1970-01-01
  • 2016-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多