简而言之:
std::get<T&>('tuple-like')
在MSVC中使用范围库时不起作用,我想知道根据C++标准期望什么。
我无法让下面的代码在 MSVC 19.40 上正确编译。不过,它确实适用于 gcc 和 clang,但我还没有找到支持 MSVC 行为的信息。
示例代码
#include <tuple>
#include <ranges>
#include <algorithm>
int main() {
using namespace std::views;
char foo{};
std::ranges::for_each(zip(iota(0, 2) | transform([&](int i) -> char& { return foo; })),
[] (auto t) { auto bar = std::get<char&>(t); });
return 0;
}
错误信息
error C2039: '_Ttype': is not a member of 'std::_Tuple_element<_Ty,std::tuple<>>'
with
[
_Ty=char &
]
我应该期待
std::get
在这里工作吗?还是我错过了什么?
我相信这是由于P2609R3的实施,它改变了
for_each
的约束,有效地要求以下内容有效:
iter_value_t<It> v = *it;
f(proj(v));
(其中
proj
默认为 std::identity{}
,返回参数不变)
当
It
是zip_view
的迭代器时,iter_value_t<It>
是std::tuple<int>
,不支持std::get<int&>
,因为它没有char&
元素。
因此,lambda 表达式不满足 P2609R3 之后的要求,并且 MSVC 发出错误是正确的。
另请注意,相同的代码不适用于最新的 gcc 或最新的 clang:https://godbolt.org/z/3Pv71rY5z.