编译器要求自定义迭代器具有整数类型,才能将其视为前向迭代器

问题描述 投票:0回答:1

我正在为自定义集合编写迭代器:

template <typename T>
class List
{
public:
    class Iterator
    {

    public:

        using difference_type = T;
        using value_type = T;
        using pointer = const T*;
        using reference = const T&;
        using iterator_category = std::forward_iterator_tag;

        Iterator(T* ptr = nullptr) : _ptr(ptr) {}
        Iterator& operator++() { _ptr++; return *this; }
        Iterator operator++(int) { Iterator retval = *this; ++(*this); return retval; }
        std::strong_ordering operator<=>(Test& other) { return _x <=> other._x; }
        bool operator==(Iterator other) const { return _ptr == other._ptr; }
        bool operator!=(Iterator other) const { return !(_ptr == other._ptr); }
        reference operator*() const { return *_ptr; }
        pointer operator->() const { return _ptr; }
        reference operator=(const T& value) { *_ptr = value; return value; }

    private:
        T* _ptr;

    };

    Iterator begin() { return Iterator(_data); }
    Iterator end() { return Iterator(_data + 4); }

    List() // Generate generic data
    {
        for (int i = 0; i < 5; i++)
        {
            _data[i] = i + 1;
        }
    }

private:
    T _data[5];
};

这需要是一个前向迭代器,但是当我使用静态断言检查它时,我只能使用

List<T>
实例,其中类型
T
是整数类型。下面是非整数类型
float
和小型
Test
类的示例。我还使用相同的静态断言测试了默认的
std::vector<Test>
迭代器,并且没有收到错误。

class Test
{
public:
    Test(int x = 0) : _x(x) {}
    void Increment() { _x++; }
    std::strong_ordering operator<=>(Test& other) { return _x <=> other._x; }
    int operator=(int x) { _x = x; return x; }
    friend std::ostream& operator<<(std::ostream& os, const Test& m) { return os << m._x; };

private:
    int _x;
};

int main()
{
    List<int> container1;
    List<Test> container2;
    List<float> container3;
    std::vector<Test> container4;

    static_assert(std::forward_iterator<decltype(container1.begin())>); // no error
    static_assert(std::forward_iterator<decltype(container2.begin())>); // ERROR
    static_assert(std::forward_iterator<decltype(container3.begin())>); // ERROR
    static_assert(std::forward_iterator<decltype(container4.begin())>); // no error

    // This loop works correctly if the static asserts are commented out
    for (List<int>::Iterator it = container1.begin(); it != container1.end(); it++)
    {
        std::cout << *it << "\n";
    }


    return 0;
}

我正在使用 C++20 ISO 标准和 Visual C++ 编译器。展开错误会得到这个错误堆栈跟踪,并以错误“不满足约束”结束。该错误引用了 __msvc_iter_core.hpp 中的这一行:

template <class _Ty>
concept _Integer_like = _Is_nonbool_integral<remove_cv_t<_Ty>> || _Integer_class<_Ty>;

我不知道为什么需要整数类型。我不认为

Test
类是问题,因为断言与向量迭代器一起使用,但我在 Iterator 类中没有看到任何需要 T 为整数的内容。为什么要测试这个要求?

c++ vector iterator c++20
1个回答
0
投票

感谢 Miles Budnek 和 Raymond Chen 在问题评论中指出了问题。

迭代器的差异类型必须是整型,并且由于我的代码的差异类型为 T,任何非整型 T 都会导致错误。

将此写为答案,以便我可以将问题标记为已回答。

© www.soinside.com 2019 - 2024. All rights reserved.