【问题标题】:Overloading template class with template function用模板函数重载模板类
【发布时间】:2017-09-26 20:09:07
【问题描述】:

C++ 允许在一个命名空间中使用同名的类和函数:

struct S {};
void S() {}

在这种情况下,纯名称S 表示函数S。要改用 struct,您需要在名称前显式添加 struct

也可以制作函数模板,同时使用它们:

template <class T>
void S() {}

struct S {};

但是禁止使用模板结构

void S() {}

template <class T>
struct S {};

gives error 像这样:

error: redefinition of 'S' as different kind of symbol

这是什么原因?为什么不允许在这里使用模板结构?是否存在在S 之前使用显式关键字struct (如非模板版本)如果允许的话无法解决名称冲突的情况?也许有提案存在?

【问题讨论】:

  • 有没有一个类型和一个函数同名不会混淆的情况?有什么好处?
  • 猜猜:出于兼容性原因从 C 继承的一个坏主意?这可以很好地解释事情,但我不知道这是不是真的。
  • @tobi303 一个已知的例子是stat 函数。你只需要记住一个名字:)
  • 那不是c函数吗?我不知道 C,但我不知道在 c++ 中有什么理由拥有同名的函数和类型
  • @tobi303 当然。但 c++ 大多与 c 代码兼容。我也认为没有理由禁止这样做。

标签: c++ templates overloading


【解决方案1】:

C++ 允许在一个命名空间中使用同名的类和函数。

   struct S {};
   void S() {}

通常当您声明struct S 时,您可以通过两种方式引用类型:Sstruct S。但这只是在您声明其他名为 S 的东西之前,例如,一个函数。当你这样做时,类型的名称不再是S。仅限struct S。名称S 是为函数保留的。

这样做是为了与 C 兼容。C 代码经常使用此设备。与 C++ 不同,C 将 struct 和 union 标签放在与普通标识符不同的名称空间中,struct S 不能简单地称为 S

因此,为了能够编译使用该设备的 C 代码,C++ 对作为不同类型标识符重用的结构标记进行了例外处理。

由于class 几乎是struct 的同义词,因此class 关键字也是如此。

但是C没有模板,不需要为它们提供向后兼容性,所以类模板没有这样的例外。

【讨论】:

  • 但是我们通过禁止这种重载来赢得什么?
  • @alexolut 我们正在赢得安心。不用担心不必要的复杂性总是好的。顺便说一句,这并没有超载。
  • 我们可以编写名为 type 的模板生成函数。例如。 struct S&lt;T&gt; S(T t) { return struct S&lt;T&gt;(t); } 而不是 makeS 函数。在 C++17 相同的调用中,即 S(t) 不使用显式类型仅通过模板推导指南允许。
  • 不是这样的。这是一个“结构和另一件事”。可以是函数,也可以是函数模板,也可以是变量,没关系。
  • 不管怎样,“为什么 C++ 没有我最喜欢的特性”是一场毫无结果的讨论。
【解决方案2】:

我认为允许函数模板名称与其他名称相同以允许重载,而根据

,明确禁止类模板名称与其他名称匹配

14 个模板 [temp]

  1. 类模板不得与同一范围 (3.3) 中的任何其他模板、类、函数、变量、枚举、枚举器、命名空间或类型具有相同的名称,但 (14.5.5) 中规定的除外。

[update] 这篇文章的其余部分让我认为函数模板没有导致相同错误的情况违反了标准要求:

除了函数模板可以被同名的非模板函数(8.3.5)或其他同名的函数模板(14.8.3)重载外,在命名空间中声明的模板名称范围或班级 范围在该范围内应该是唯一的

和 VS/clang/gcc 似乎不同意godbolt

【讨论】:

  • 问题是“为什么”,而不是“什么”。
  • @n.m.同意。我想将 OT 的问题重新表述为:如果允许,谁能发布一段最终会陷入痛苦的代码。
  • @n.m.我的猜测是相同的名称只允许与 c 兼容。有了模板,就没有理由关心向后兼容性
  • BTW 切换定义顺序让 CL 编译器开心。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
相关资源
最近更新 更多