std::common_reference_with 在元组上的行为不一致。哪个是正确的?

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

背景:

我正在尝试移植一个库以在 MSVC 上进行编译。 该库将数据存储在向量元组中 (

std::tuple<std::vector<Ts>...>
),并使用自定义迭代器同时迭代所有向量(类似于 zip_iterator 的作用)。

迭代器定义的类型如下所示(假设

Ts...
->
<int, int>
):

`value_type` is `std::tuple<int, int>`  
`reference`  is `std::tuple<int&, int&>`

问题是,在最新的 MSVC (v. 19.35) 上,这个迭代器不满足

std::input_iterator
的概念,而在 gcc/clang 上却满足它。

经过进一步调查,我发现失败是由于

std::common_reference
概念在元组上的行为不一致造成的。

问题:

以下

static_assert
在MSVC上失败,而在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");

这里是 Godbolt(还有迭代器示例)

问题:

std::tuple<int, int>&
这样的类型应该有一个“
common_reference_with
std::tuple<int&, int&>
吗? MSVC 说不,gcc 说可以。
根据 C++20 及以后的标准,这两种行为中的哪一种是预期的?

是否有任何简单的方法可以使该迭代器成功通过 MSVC 上的迭代器概念检查(即强制两种类型具有共同的引用)?

我还在 Eric Niebler 的 std::common_reference (SO)proxy iterators(在他的博客上)上找到了一些很好的答案。

但是,我不清楚 C++20 及更高版本中应该发生什么。

c++ tuples language-lawyer c++-concepts c++-standard-library
1个回答
5
投票

std::tuple<int, int>&
这样的类型应该有一个 “common_reference_with”
std::tuple<int&, int&>

是的,P2321保证它们具有共同的参考类型

tuple<int&, int&>
和型号
common_reference_with

由于

common_reference
tuple
的这种增强是C++23功能,因此您需要将MSVC编译器选项更改为
/std:c++latest
才能使其工作

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