【问题标题】:What was the issue solved by the new "using" syntax for template typedefs?模板类型定义的新“使用”语法解决了什么问题?
【发布时间】:2013-10-17 22:26:35
【问题描述】:

在 C++11 中,您可以通过执行类似的操作来创建“类型别名”

template <typename T>
using stringpair = std::pair<std::string, T>;

但这与您期望的模板 typedef 的外观有所不同:

template <typename T>
typedef std::pair<std::string, T> stringpair;

所以这就提出了一个问题——他们为什么需要提出一种新的语法?旧的typedef 语法有什么不适合的?

我知道最后一点没有编译,但为什么不能编译?

【问题讨论】:

  • 可能是新语法更具可读性,因为名称与类型分开,用 = 分隔。更不用说把别名放在现有类型后面似乎不像typedef那样在我的大脑中向后工作。
  • 我仍然认为这是“我们讨厌typedef,但出于历史原因使用它;但是,现在我们正在添加新功能,我们有机会流浪。”跨度>
  • @TemplateRex,什么是“模板”?
  • @Charles 错字,已修复!

标签: c++ templates c++11 typedef template-aliases


【解决方案1】:

我只提到 stroustrup 本人:

http://www.stroustrup.com/C++11FAQ.html#template-alias

关键字using用于获取线性符号“名称后跟 它指的是什么。”我们尝试了传统和复杂的 typedef 解决方案,但从未设法获得完整和连贯的 解决方案,直到我们确定了一种不那么晦涩的语法。

【讨论】:

  • typedefs IMO 很难读,因为原始类型和别名之间没有分隔符
  • @dornhege 我很想知道他们应该尝试了什么以及它是如何失败的。这是我能找到的唯一一个似乎可以解决这个问题的参考,但它基本上说 - 相信我,这很糟糕。我想知道关键缺陷是什么。
  • @shoosh: typedef 已由现有语法描述。亲自尝试一下,正式确定如何将模板化添加到语言中,看看能走多远。
  • @KerrekSB:但除非 shoosh 和 Stroustrup 一样聪明,否则这是行不通的。它会给出 shoosh 做不到的原因,但可能不是 Stroustrup 做不到的原因(特别是考虑到 Stroustrup 的问题显然如此复杂,以至于这里没有人能清楚地表达出来)。
  • 或者它们不是实际问题,这在我看来更有可能。
【解决方案2】:

来自 WG21 提案 N1489 Template aliases(由 Stroustrup 和 Dos Reis 提出):

建议(重新)使用关键字typedef,就像在 论文 [4] 介绍模板别名:

 template<class T> 
 typedef std::vector<T, MyAllocator<T> > Vec;

这种表示法的优点是使用了已知的关键字 引入类型别名。但是,它也显示出几个缺点 其中使用已知的关键字引入的混淆 在别名未指定的上下文中类型名称的别名 一个类型,但是一个模板; Vec 不是类型的别名,也不应该 被视为 typedef-name。 Vec这个名字是这个家族的名字 std::vector&lt;o, MyAllocator&lt;o&gt; &gt; 其中子弹是占位符 对于类型名称。因此我们不建议使用 typedef 语法。

另一方面是句子

template<class T> 
using Vec = std::vector<T, MyAllocator<T> >;

可以阅读/解释为:从现在开始,我将使用Vec&lt;T&gt; 作为 std::vector&lt;T, MyAllocator&lt;T&gt; &gt; 的同义词。有了这样的阅读, 别名的新语法似乎合乎逻辑。

上述引用中提到的论文 [4] 是先前的提案 WG21 N1406 Proposed Addition to C++: Typedef Templates(由 Herb Sutter 提出)。它使用不同的语法(typedef 与 using)以及不同的命名法(typedef 模板与模板别名)。 Herb 提出的语法没有成功,但有时可以在非正式讨论中找到该命名法。

【讨论】:

  • 虽然解释有点迂腐,但我认为这里有一个非常直截了当的论点:模板的 typedef 不会定义类型,而是模板。
【解决方案3】:

(tl;dr:using 支持模板,而 typedef 不支持。)


正如您已经知道的那样,这两个示例之间的区别没有模板没什么:

[C++11: 7.1.3/2]: typedef-name 也可以由 alias-declaration 引入。 using 关键字后面的标识符变成 typedef-name 并且标识符后面的可选 attribute-specifier-seq 属于该 typedef-name。 它与typedef 说明符引入的语义相同。特别是,它没有定义一个新的类型并且它不会出现在type-id中。

但是,模板typedefs 不存在!

[C++11: 14.5.7/1]: 一个template-declaration,其中声明是一个alias-declaration(第 7 条),它将标识符声明为一个别名模板。别名模板是一系列类型的名称。别名模板的名称是 template-name。

他们为什么不简单地重用typedef 语法?好吧,我认为typedef 只是“旧”样式,鉴于在其他情况下使用using,因此决定新功能应采用using 形式以保持一致性。

【讨论】:

  • 这并不能真正回答所提出的问题。阅读问题。
  • @shoosh:是的,确实如此。不是很好,但确实如此。不客气。
【解决方案4】:

新语法的另一个原因 - 函数、数组和类似结构的 typedef 变得更易于理解。

在之前/之后引用数组:

typedef int(&my_type)[3];
using my_type = int(&)[3];

之前/之后的函数指针数组:

typedef void(*my_type[3])();
using my_type = void(*[3])();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    • 1970-01-01
    • 2014-06-21
    • 2017-08-26
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多