我正在为自定义集合编写迭代器:
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 为整数的内容。为什么要测试这个要求?
感谢 Miles Budnek 和 Raymond Chen 在问题评论中指出了问题。
迭代器的差异类型必须是整型,并且由于我的代码的差异类型为 T,任何非整型 T 都会导致错误。
将此写为答案,以便我可以将问题标记为已回答。