-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Describe the bug
According to [common.iter.types]/(1.3) (to be fixed by LWG-3660), whether std::iterator_traits<std::common_iterator<I, S>>::pointer is not void depends on std::common_iterator<I, S>::operator->, not only I::operator->. However, the MSVC STL implementation currently only detects I::operator->, which sometimes gives wrong result.
Note that while the current implementation is buggy, the portion fixed by LWG-3660 has been implemented.
Command-line test case
C:\Temp>type repro.cpp
#include <iterator>
struct zero_sentinel {
template<std::integral I>
friend constexpr bool operator==(zero_sentinel, const I* it)
{
return *it == I{};
}
};
using common_pchar = std::common_iterator<const char*, zero_sentinel>;
static_assert(std::same_as<std::iterator_traits<common_pchar>::pointer, const char* const&>);
int main() {}
C:\Temp>cl /EHsc /W4 /WX /std:c++20 .\repro.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30139 版
版权所有(C) Microsoft Corporation。保留所有权利。
repro.cpp
.\repro.cpp(12): error C2607: 静态断言失败
Expected behavior
The program compiles.
STL version
Microsoft Visual Studio Community 2019
Version 16.11.9
Additional context
See also Compile Explorer link.
libc++ and libstdc++ have also implemented the portion fixed by LWG-3660. Currently only libc++ correctly implements the requirement. libstdc++ correctly detects std::common_iterator<I, S>::operator->, but the implementation of operator-> is buggy (missing parentheses against the deduction of decltype(auto)).