【发布时间】:2021-08-27 21:36:21
【问题描述】:
我有一个模板类,用于对对象的视图建模,例如 std::shared_ptr 和 std::weak_ptr,但没有任何拥有语义。该类内部包含一个指向查看对象的指针和一个在类销毁时调用的函子(这对于对查看的对象进行引用计数,或对查看的资源的线程安全锁定和释放很有用)。
与标准库对应项一样,我希望我的类在拥有的对象是数组 (T[]) 时按预期运行。我面临的问题来自这样一个事实,即在我的理解中,指向未知边界数组的指针是非法的 C++。更具体地说,假设 T 类的模板参数是 int[],当我在我的课堂上写:
T& operator*() {
return *internal_pointer;
}
我实际上是在调用未定义的行为。 (或者,可能是一些非标准的编译器扩展?)
我知道,为了避免这些情况,需要一个类模板特化——一个指向元素类型 int 的指针可以被保留,并被类视为指向数组的指针。但是,我的问题是:为什么对未知边界数组的指针和引用是非法的?
在我看来,使用它们是最合乎逻辑的事情,因为您正在查看的是一个数组,您可能不一定知道其长度:这保留了查看对象的类型,而一个指向在我看来,元素类型只不过是一种 hack。
是否有任何技术原因不允许引用未知边界的数组?
【问题讨论】:
-
一切都有界限。如果在编译时不知道容器的容量,请使用
std::vector或std::list。 -
一个不合法的事情是从一个函数返回一个数组
-
指向未知边界数组的指针或引用在 C++ 中是完全合法的——它只是不知道它的长度。例如,您可以轻松地将
int[6]转换为int(*)[]或int(&)[]-- 至少从 C++20 开始。 -
对不起,如果这是一个迟到的评论,但我很难找到正确的方法来进行转换。我正在使用 C++17,当我从
int(*)[2]类型中执行static_cast<int(*)[]>时,编译器会抱怨。我还尝试通过另一个间接方式转换类型(将指针转换为指向数组的指针),但这仍然无济于事。我对使用reinterpret_cast持怀疑态度,因为无法保证结果指针的可用性,并且通过void*进行转换似乎是作弊。你知道解决办法吗?