gpt4 book ai didi

c++ - 无法将右值 std::array 转换为 std::span

转载 作者:行者123 更新时间:2023-12-04 14:53:17 25 4
gpt4 key购买 nike

考虑以下代码。

#include <array>
#include <span>

std::array<int, 2> Foo()
{
return {1, 2};
}

int main()
{
std::array a = {3, 4};
std::span s1 = a;

// std::span s2 = Foo(); // Nope
// std::span s3 = std::move(a); // Nope
// std::span s4 = std::array<int, 2>{5, 6}; // Nope

// MSVC 19.29: 'initializing': cannot convert from 'std::array<int,2>' to 'std::span<int,18446744073709551615>'
// GCC 12.0.0: conversion from 'std::array<int, 2>' to non-scalar type 'std::span<int, 18446744073709551615>' requested
// clang 13.0.0: actually compiles!
}
好像 std::array可以转换为 std::span当它是仅在 clang 上的右值时。
我不确定这是否是问题的根源,但这里是 MSVC 对 std::array 的实现 std::span的相关构造函数.
    template <class _OtherTy, size_t _Size>
requires (_Extent == dynamic_extent || _Extent == _Size)
&& is_convertible_v<_OtherTy (*)[], element_type (*)[]>
constexpr span(array<_OtherTy, _Size>& _Arr) noexcept : _Mybase(_Arr.data(), _Size) {}

template <class _OtherTy, size_t _Size>
requires (_Extent == dynamic_extent || _Extent == _Size)
&& is_convertible_v<const _OtherTy (*)[], element_type (*)[]>
constexpr span(const array<_OtherTy, _Size>& _Arr) noexcept : _Mybase(_Arr.data(), _Size) {}
乍一看,我看不出有什么问题。右值应该绑定(bind)到一个 const 左值引用。
我的问题是:这段代码应该编译(这是前一个编译器的问题)还是不编译(这是后一个编译器的问题)?

最佳答案

TL;博士。这只是因为 libc++ 还没有实现
p1394r4 .

问题是在libstd++MSVC-STL , std::span具有以下 CTAD:

template<typename _Range>
span(_Range &&)
-> span<remove_reference_t<ranges::range_reference_t<_Range&>>>;
当我们调用 std::span{std::array{0}}span的类型将被推导出 span<int> ,我们将调用 span<int>::span(const array<int, 1>&) ,但是这个构造函数有 following constraints :

Constraints: Let U be remove_­pointer_­t<decltype(data(arr))>.

  • extent == dynamic_­extent || N == extent is true, and
  • is_­convertible_­v<U(*)[], element_­type(*)[]> is true.

由于返回类型为 arr.data()const int*element_typeintis_convertible_v<const int(*)[], int(*)[]>的值为假,因此不满足约束。

此CATD 在 libc++ 中不可用, 所以 std::span{std::array{0}}将使用以下CATD:
template<class _Tp, size_t _Sz>
span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>;
并调用 span<const int, 1>::span(array<const int, 1>&) ,这只是...工作。

关于c++ - 无法将右值 std::array 转换为 std::span,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68659197/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com