11
Background:
I’m trying to port a library to compile on MSVC.
That library stores data in a tuple of vectors (std::tuple<std::vector<Ts>...>
), and uses a custom iterator to iterate over all vectors simultaneously (similar to what a zip_iterator does).
The iterator defines types that look like this (assuming Ts...
-> <int, int>
) :
`value_type` is `std::tuple<int, int>`
`reference` is `std::tuple<int&, int&>`
The problem is that on latest MSVC (v. 19.35), this iterator does not satisfy the concept of std::input_iterator
, while it does satisfy it on gcc/clang.
On further investigation, i found the failure to be due to inconsistent behaviour of the std::common_reference
concept on tuples.
Issue:
The following static_assert
fails on MSVC, while it doesn’t fail on gcc/clang
using T = std::tuple<int, int>&;
using U = std::tuple<int&, int&>;
static_assert(std::common_reference_with<T, U>, "failed common_reference_with");
Here it is on Godbolt (with an iterator example as well)
Question:
Is a type like std::tuple<int, int>&
supposed to have a "common_reference_with
" std::tuple<int&, int&>
? MSVC says no, gcc says yes.
Which of the two behaviours should be expected according to the standard in C++20 and forward?
Is there any easy way to make this iterator succeed the iterator concept checks on MSVC (ie, force the two types to have a common reference)?
I also found some great answers by Eric Niebler, on std::common_reference (SO) and on proxy iterators (on his blog).
However, it’s not clear to me what is supposed to happen in C++20 and later.
1 Answer
Reset to default
10
Is a type like
std::tuple<int, int>&
supposed to have a
"common_reference_with"std::tuple<int&, int&>
?
Yes, P2321 guarantees that they have common reference type tuple<int&, int&>
and model common_reference_with
.
Since such enhancement of common_reference
for tuple
is a C++23 feature, you need to change the MSVC compiler option to /std:c++latest
to make it work.
It is worth noting that P2165 makes tuple
compatible with other tuple
-like objects such as array
, pair
and ranges::subrange
, so it also has a valid common_reference
type with the other three.
Not the answer you're looking for? Browse other questions tagged
or ask your own question.
or ask your own question.
|