【问题标题】:Prevent alias to alias redefinition C++防止别名重新定义别名 C++
【发布时间】:2019-01-21 05:07:35
【问题描述】:

我想对用户隐藏库实现,并为公共 API 提供实现别名,以减少代码重复。因此,如果我有两个逻辑上不同的 API 结构,但它们的实现是相同的,那么实现将被别名,如代码 sn-p 所示。

// library implementation
namespace impl {
    struct A {};
}

// library public API
using A1 = impl::A;
using A2 = impl::A;

// library usage
int main(int argc, char* argv[]) {
    using type = A1;
    // do some stuff
    using type = A2; // prevent this redefinition with reporting warning or error
    // do some more stuff
    return 0;
}  

但是如果用户决定像在代码 sn-p 中那样重新定义库公共 API 的别名,它可能会导致隐藏的逻辑错误,因为它编译得很好。所以问题是:

如果重新定义的别名被引用到相同的类型,是否可以防止别名到别名的重新定义?

【问题讨论】:

  • 这是有问题的,因为typeA1A2impl::A都是同一个类型,也就是说真的没有重定义。也许如果您尝试解释您尝试解决的原始问题是什么,我们或许可以帮助您解决这个问题? IE。 为什么你想要一个像你展示的那样的解决方案的原因。 Very related reading about the XY problem.
  • @Someprogrammerdude 谢谢你的评论。我已经更新了我的问题
  • 您可能想查找namespace versioning
  • 还要注意A2* X = (A1*)Y 在你的宇宙中是完全合法的。如果您想伪装类型,一种方法是编写一个受保护的包装类,该类对要发布的成员具有 public using 声明。
  • 别名不是不同的事物,它是同一事物的不同名称。 (在这种情况下,事物 == 类型)。您不能禁止用户对现有事物使用他们想要的任何名称。如果你需要不同的东西而不是不同的名字,别名对你没有帮助。

标签: c++ c++11 c++14


【解决方案1】:

如果你指向相同的类型,编译器对此完全没有问题,恐怕你对此无能为力。

来自typedef 关键字,在您的情况下,它基本上等同于using 关键字:

https://en.cppreference.com/w/cpp/language/typedef

Typedef 不能用于更改现有类型名称的含义 (包括 typedef 名称)。一旦声明,typedef-name 只能是 重新声明以再次引用相同的类型。

因此,使用不同的 type-id 重新声明 typedef-name 是错误的。重新声明具有相同 type-id 的 typedef-name 没有任何作用。

【讨论】:

    【解决方案2】:

    最简单的解决方法可能是继承:

    struct A1 : public impl::A
    {
      using A::A;
    };
    struct A2 : public impl::A
    {
      using A::A;
    };
    

    这定义了新类型,但重用了实现。您甚至可以使用私有继承,但这将需要更多 using 其他成员的声明。

    【讨论】:

      猜你喜欢
      • 2019-06-05
      • 2013-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多