【问题标题】:Using aliases for strictly typing function parameters使用别名严格键入函数参数
【发布时间】:2015-10-04 21:38:30
【问题描述】:

可以使用别名来更改函数的文字签名:

using String = std::string;

void Print(String s) { ... };

但这并不允许使用std::string 调用Print

Print(std::string{"Hello world"}); // Still works

这是有道理的——别名严格来说是为了简化类型的名称,它没有定义新的类型。

除了子类化,即not a good idea,是否有一种机制可以实现函数参数的名称严格类型化?这样做的直接后果是这也是可能的:

using StringA = std::string;
using StringB = std::string;

void Print(StringA s) { ... };
void Print(StringB s) { ... };

Print(StringA{"Hello world"});
Print(StringB{"Hi everyone"});

我当前的解决方案是定义简单的包装类,这些类包含我想要别名为成员的类型。这并不理想,因为它需要将成员类的接口复制到包装器中,这在使用别名时不是必需的。

【问题讨论】:

  • 请注意,第二个答案表明如果您小心的话,在您的情况下创建派生类可能是合理的:stackoverflow.com/a/6014514/951890
  • 这是一个很好的分析。感谢您指出这一点,我经常忽略未选择的答案,但这是一个令人谦卑的阅读。

标签: c++ c++11 overloading alias typedef


【解决方案1】:

您采取了正确的方法。包装原始类型的对象是您目前可以做的最好的事情。

我最近在 CppCon 2015 上谈到了这个话题,并开源了一个库,可以方便地为整数类型制作“不透明 typedef”: https://sourceforge.net/projects/opaque-typedef/

请注意,自定义新类型的界面、删除对您的目的而言可能是错误的操作以及添加与其他类型的有意互操作性可能是有益的。 Slides from my presentation.

【讨论】:

  • 我实际上看到了你的演讲(我是你小组中的闪电演讲者之一),这让我怀疑是否已经存在用于不透明 typedef 的语言机制。
【解决方案2】:

标准使 typedefs 和 alias 成为另一种类型而不是新类型的同义词:

7.1.3/1:使用 typedef 说明符声明的名称成为 typedef-name。在其声明范围内,typedef-name 是 语法上等同于关键字并命名关联的类型 以第 8 条中描述的方式使用标识符。 A typedef-name 因此是另一种类型的同义词。 typedef-name 不引入 一种新类型,就像类声明或枚举声明一样。

7.1.3/2: typedef-name 也可以由别名声明引入。 using 关键字后面的标识符变为 类型定义名称。它具有相同的语义,就好像它是由 typedef 说明符。特别是,它没有定义新的类型和 它不应出现在 type-id 中。

所以不幸的是,您将不得不继续使用您的类包装器来引入不同的类型并能够在此基础上重载函数。

【讨论】:

    【解决方案3】:

    不,如果不实际创建新类型(类、结构、枚举),就无法获得新类型。

    不过,有a brand new proposal添加这样的机制,可能是用newtype作为关键字,而不是typedef

    【讨论】:

      猜你喜欢
      • 2017-11-25
      • 2019-09-05
      • 2018-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-08
      相关资源
      最近更新 更多