-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Closed
Labels
enhancementSomething can be improvedSomething can be improvedfixedSomething works now, yay!Something works now, yay!
Description
Describe the bug
The non-Standard extensions stdext::checked_array_iterator and stdext::unchecked_array_iterator don't participate in constness conversions like modern iterators do:
Lines 521 to 523 in 5ef22f2
| template <class _Ptr> | |
| class checked_array_iterator { // wrap a pointer with checking | |
| static_assert(_STD is_pointer_v<_Ptr>, "checked_array_iterator requires pointers"); |
Lines 718 to 720 in 5ef22f2
| template <class _Ptr> | |
| class unchecked_array_iterator { // wrap a pointer without checking, to silence warnings | |
| static_assert(_STD is_pointer_v<_Ptr>, "unchecked_array_iterator requires pointers"); |
Command-line test case
C:\Temp>type meow.cpp
#include <array>
#include <iostream>
#include <iterator>
#include <type_traits>
using namespace std;
using stdext::checked_array_iterator;
using stdext::unchecked_array_iterator;
#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)
template <typename From, typename To>
void verify_convertible() {
STATIC_ASSERT(is_convertible_v<From, To>);
STATIC_ASSERT(is_constructible_v<To, From>);
STATIC_ASSERT(is_assignable_v<To&, From>);
}
template <typename From, typename To>
void verify_NOT_convertible() {
STATIC_ASSERT(!is_convertible_v<From, To>);
STATIC_ASSERT(!is_constructible_v<To, From>);
STATIC_ASSERT(!is_assignable_v<To&, From>);
}
struct Base {};
struct Derived : Base {};
int main() {
array<int, 5> arr{{10, 20, 30, 40, 50}};
{
array<int, 5>::iterator standard_iter = arr.begin();
standard_iter += 1;
cout << *standard_iter << "\n";
array<int, 5>::const_iterator standard_const_iter = arr.cbegin();
standard_const_iter += 2;
cout << *standard_const_iter << "\n";
standard_const_iter = standard_iter;
cout << *standard_const_iter << "\n";
verify_convertible<array<int, 5>::iterator, array<int, 5>::const_iterator>();
verify_NOT_convertible<array<Derived, 5>::iterator, array<Base, 5>::iterator>();
}
{
checked_array_iterator<int*> checked_iter{arr.data(), arr.size()};
checked_iter += 1;
cout << *checked_iter << "\n";
checked_array_iterator<const int*> checked_const_iter{arr.data(), arr.size()};
checked_const_iter += 2;
cout << *checked_const_iter << "\n";
#ifndef AVOID_ERRORS
checked_const_iter = checked_iter;
cout << *checked_const_iter << "\n";
verify_convertible<checked_array_iterator<int*>, checked_array_iterator<const int*>>();
verify_NOT_convertible<checked_array_iterator<Derived*>, checked_array_iterator<Base*>>();
#endif // AVOID_ERRORS
}
{
unchecked_array_iterator<int*> unchecked_iter{arr.data()};
unchecked_iter += 3;
cout << *unchecked_iter << "\n";
unchecked_array_iterator<const int*> unchecked_const_iter{arr.data()};
unchecked_const_iter += 4;
cout << *unchecked_const_iter << "\n";
#ifndef AVOID_ERRORS
unchecked_const_iter = unchecked_iter;
cout << *unchecked_const_iter << "\n";
verify_convertible<unchecked_array_iterator<int*>, unchecked_array_iterator<const int*>>();
verify_NOT_convertible<unchecked_array_iterator<Derived*>, unchecked_array_iterator<Base*>>();
#endif // AVOID_ERRORS
}
}
C:\Temp>cl /EHsc /nologo /W4 /DAVOID_ERRORS meow.cpp && meow
meow.cpp
20
30
20
20
30
40
50
C:\Temp>cl /EHsc /nologo /W4 meow.cpp && meow
meow.cpp
meow.cpp(57): error C2679: binary '=': no operator found which takes a right-hand operand of type 'stdext::checked_array_iterator<int *>' (or there is no acceptable conversion)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\iterator(710): note: could be 'stdext::checked_array_iterator<const int *> &stdext::checked_array_iterator<const int *>::operator =(stdext::checked_array_iterator<const int *> &&)'
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\iterator(710): note: or 'stdext::checked_array_iterator<const int *> &stdext::checked_array_iterator<const int *>::operator =(const stdext::checked_array_iterator<const int *> &)'
meow.cpp(57): note: while trying to match the argument list '(stdext::checked_array_iterator<const int *>, stdext::checked_array_iterator<int *>)'
meow.cpp(75): error C2679: binary '=': no operator found which takes a right-hand operand of type 'stdext::unchecked_array_iterator<int *>' (or there is no acceptable conversion)
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\iterator(850): note: could be 'stdext::unchecked_array_iterator<const int *> &stdext::unchecked_array_iterator<const int *>::operator =(stdext::unchecked_array_iterator<const int *> &&)'
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\iterator(850): note: or 'stdext::unchecked_array_iterator<const int *> &stdext::unchecked_array_iterator<const int *>::operator =(const stdext::unchecked_array_iterator<const int *> &)'
meow.cpp(75): note: while trying to match the argument list '(stdext::unchecked_array_iterator<const int *>, stdext::unchecked_array_iterator<int *>)'
Expected behavior
Code should compile.
STL version
Visual Studio Community 2019 Preview
16.7.0 Preview 3.1
Additional context
This item is also tracked on Developer Community as DevCom-241515 and by Microsoft-internal VSO-146139 / AB#146139.
Metadata
Metadata
Assignees
Labels
enhancementSomething can be improvedSomething can be improvedfixedSomething works now, yay!Something works now, yay!