【问题标题】:Reference to an array of unknown bound (C++)对未知边界数组的引用 (C++)
【发布时间】:2021-08-27 21:36:21
【问题描述】:

我有一个模板类,用于对对象的视图建模,例如 std::shared_ptrstd::weak_ptr,但没有任何拥有语义。该类内部包含一个指向查看对象的指针和一个在类销毁时调用的函子(这对于对查看的对象进行引用计数,或对查看的资源的线程安全锁定和释放很有用)。

与标准库对应项一样,我希望我的类在拥有的对象是数组 (T[]) 时按预期运行。我面临的问题来自这样一个事实,即在我的理解中,指向未知边界数组的指针是非法的 C++。更具体地说,假设 T 类的模板参数是 int[],当我在我的课堂上写:

T& operator*() {
    return *internal_pointer;
}

我实际上是在调用未定义的行为。 (或者,可能是一些非标准的编译器扩展?)

我知道,为了避免这些情况,需要一个类模板特化——一个指向元素类型 int 的指针可以被保留,并被类视为指向数组的指针。但是,我的问题是:为什么对未知边界数组的指针和引用是非法的?

在我看来,使用它们是最合乎逻辑的事情,因为您正在查看的是一个数组,您可能不一定知道其长度:这保留了查看对象的类型,而一个指向在我看来,元素类型只不过是一种 hack。

是否有任何技术原因不允许引用未知边界的数组?

【问题讨论】:

  • 一切都有界限。如果在编译时不知道容器的容量,请使用std::vectorstd::list
  • 一个不合法的事情是从一个函数返回一个数组
  • 指向未知边界数组的指针或引用在 C++ 中是完全合法的——它只是不知道它的长度。例如,您可以轻松地将 int[6] 转换为 int(*)[]int(&)[] -- 至少从 C++20 开始。
  • 对不起,如果这是一个迟到的评论,但我很难找到正确的方法来进行转换。我正在使用 C++17,当我从 int(*)[2] 类型中执行 static_cast<int(*)[]> 时,编译器会抱怨。我还尝试通过另一个间接方式转换类型(将指针转换为指向数组的指针),但这仍然无济于事。我对使用reinterpret_cast 持怀疑态度,因为无法保证结果指针的可用性,并且通过void* 进行转换似乎是作弊。你知道解决办法吗?

标签: c++ arrays templates


【解决方案1】:

我面临的问题来自于这样一个事实:根据我的理解,指向未知边界数组的指针是非法的 C++。

你错了。指向未知边界数组的指针在 C++ 中不是非法的。

我实际上是在调用未定义的行为。 (或者,可能是一些非标准的编译器扩展?)

都不是(只要指针有效)。即使T 是一个未知边界的数组,显示的函数也符合标准。

为什么对未知边界数组的指针和引用是非法的?

它们并不违法。


曾经有一种特殊情况,指向未知边界数组的指针和引用作为函数参数是非法的。这在 2014 年的缺陷解决方案中被合法化

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    相关资源
    最近更新 更多