无法使用 T = vector<T::iterator> 创建递归类型

Can't create recursive type `using T = vector<T::iterator>`

我正在尝试创建一个包含自己的迭代器作为元素的向量,但我发现无法完全扩展类型声明。

using MyVectorType = std::vector<std::vector<...>::iterator>;
// Trying to fill in the ...                 ^^^

另一种失败的方法是:

using MyVectorType = std::vector<MyVectorType::iterator>;

use of undeclared identifier 'MyVectorType' Trying to use an intermediate declaration also fails

template <class T>
using MyVectorType_incomplete = std::vector<T>;
using MyVectorType = MyVectorType_incomplete<MyVectorType_incomplete::iterator>;

error: 'MyVectorType_incomplete' is not a class,
namespace, or enumeration

显然使用指针可以解决这个问题。

struct It {
   It *iterator;
};
vector<It>;

但是这意味着您不能使用迭代器接口,基本上必须为给定的 class.

重新实现迭代器

有没有办法在 C++ 中做到这一点?

更一般地说,有没有一种方法可以像上面那样创建递归类型,在类型创建之前引用它?

using 引入了类型别名。别名是其他事物的名称。您始终可以用其他东西替换别名。事实上,您必须这样做才能找出涉及别名的类型的属性,因为别名没有自己的属性。

using MyVectorType = std::vector<MyVectorType::iterator>; // replace the name with the thing named
using MyVectorType = std::vector<std::vector<MyVectorType::iterator>::iterator>; // again
using MyVectorType = std::vector<std::vector<std::vector<std::vector<MyVectorType::iterator>::iterator>; ::iterator>::iterator>; // and again and again

所以你不能有递归类型别名。

您可以创建递归类型,但不能使用类型别名关闭循环。您可以使用指针或模板来完成。像这样的东西应该是合法的 C++:

struct my_vector : public std::vector<std::vector<my_vector>::iterator> {}

但不知道对你有多大用处

我不认为这是可能的标准。

要实现你想要的,你必须能够参考 std::vector<T>::iteratorT 是不完整的。

在 C++17 之前,T 需要完整才能实例化 std::vector<T>,因此它无法在那里工作。

自 C++17 起,标准允许使用不完整的类型 T 实例化 std::vector<T>,但是只要类型在其任何成员被引用之前是完整的,请参阅 [vector.overview]/4 post-C++20 草稿。

但是,如果要实现这样的递归,需要能够继承或者拥有std::vector<T>::iterator类型的成员。这不仅引用了 ::iterator 类型,而且还需要对其进行实例化,此时不保证可以正常工作。

让 class 继承自 std::vector<T::iterator> 也不会起作用,因为那时 T 需要完成。将 T::iterator 推迟到另一个继承的 class 也不会起作用,因为 classes 然后递归地依赖于在另一个之前完成。

根据标准库的实现方式std::vector<T>::iterator,以下可能有效,但根据标准,它在技术上是未定义的行为:

struct MakeMyVectorType : std::vector<MakeMyVectorType>::iterator  {
};

using MyVectorType = std::vector<MakeMyVectorType>;

int main() {
    MyVectorType v1(10);
    MyVectorType v2(v1.begin(), v1.end());
    v2.push_back({v1.begin()+5});
    MyVectorType v3{{v2.begin()}, {v2.end()}};
    std::cout << v1.size() << "\n";  // 10
    std::cout << v2.size() << "\n";  // 11
    std::cout << v3.size() << "\n";  // 2
}

我也不确定你会如何使用这种类型。