【问题标题】:How to restrict implicit conversion of typedef'ed types?如何限制 typedef 类型的隐式转换?
【发布时间】:2014-04-24 15:11:08
【问题描述】:

假设有两种类型:

typedef unsigned short Altitude;
typedef double Time;

为了检测一些错误,例如在编译时将高度位置的时间参数传递给函数,我想禁止从 AltitudeTime 的隐式转换,反之亦然。

我首先尝试的是声明一个没有实现的operator Altitude(Time),但编译器说它必须是一个成员函数,所以我明白它不适用于typedefed 类型。

接下来我尝试将其中一种类型转换为一个类,但似乎该项目广泛使用了许多算术,包括对doubleintbool 等的隐式转换,以及传递它们通过operator<<operator>> 往返于流中。因此,尽管这种方式让我能够找到我正在寻找的错误,但我什至没有尝试完全实现兼容类,因为这需要大量代码。

所以我的问题是:有没有更优雅的方法来防止两个特定 typedefed 类型之间的隐式转换,如果是,那么如何?

【问题讨论】:

  • typedefs 与此无关。它们不是新类型。它们是现有类型的别名。
  • 为什么是Time?已经有std::chrono::duration
  • @MSalters 因为它更符合它的目的(有很多算术),并且因为项目在 C++11 还不存在时就开始了。

标签: c++ type-conversion implicit-conversion


【解决方案1】:

typedef 只是为现有类型建立另一个名称。

因此,您的问题归结为是否可以禁用 unsigned shortdouble 之间的隐式转换,这通常是不可能的。

有两种方法可以解决这个问题:

首先,您可以使AltitudeTime 成为它们自己的类型(阅读:定义classes 而不是typedefs)并确保它们可以轻松地转换为它们的底层数字类型 -但不是彼此。

其次,您可以确保您所做的任何事情都受到语言结构的保护,例如如果您有一个函数 f 应该采用 Altitude 又名 unsigned short,您可以使用另一个函数 f 重载它,该函数采用 Time 又名 double 并导致错误。这提供了更好的重载匹配,因此可以防止这种情况下的隐式转换。

【讨论】:

  • 导致错误的重载函数是个好主意,但它只在运行时捕获错误。我不是 C++ 专家,但是没有办法在编译时检测到此类错误吗?
  • @KeithThompson:重载分辨率很大程度上是编译时检查。它是静态类型安全机制的一部分。只有 dynamic_cast 是 RTTI 检查。
  • @MSalters:是的,但据我了解,建议是提供两个重载函数,一个用于 unsigned short,它做正确的事情,另一个用于 double,“导致错误”。我在想void func(unsigned short arg){do_the_right_thing;}void func(double arg){abort();}。有没有办法让func(42.0) 之类的调用成为编译时错误?
  • @Keith: void func(double arg) = delete
  • @MSalters:从 C++11 开始,您可以使用 void func(double arg) = delete;。对于早期版本的 C,我认为您可以只声明它但永远不要定义它,这会产生链接时错误(尽管在这种情况下错误消息可能不会给您行号)。
猜你喜欢
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
  • 2020-04-19
  • 2018-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多