C++ std::span:转换构造函数的用法

C++20 std::span: Uses of converting constructor

提问人:cbhattac 提问时间:6/27/2023 最后编辑:Barrycbhattac 更新时间:6/27/2023 访问量:211

问:

C++ std::span 的转换构造函数:

template<class OtherElementType, size_t OtherExtent>
  constexpr explicit(see below) span(
     const span<OtherElementType, OtherExtent>& s) noexcept;

with constraints,可用于以下目的:

int arr[]{1, 2, 3};

span<int, 3> sf{arr};
// static span to dynamic span.
span<int> sd{sf};

// non-const to const span.
span<const int> scd{sd};
span<const int, 3> sfc{sf};

// dynamic to static span.
span<int, 3> sf2{sd};

此构造函数还有哪些其他用途可以满足此约束

is_­convertible_­v<OtherElementType(*)[], element_­type(*)[]>是真的。[ 注意:其目的是只允许将 的 限定转换为 . — 尾注 ]OtherElementTypeelement_­type

C++ 构造函数 C++20 std-span

评论

0赞 user17732522 6/27/2023
正如注释中所说,它允许任何资格转换,例如 到等。int**int const* const* const

答:

0赞 Jan Schultke 6/27/2023 #1

目的是允许在跨度之间进行隐式转换,只要此转换是合格的转换并且大小匹配即可。 它也可以用于显式转换,就像在你的例证中一样,但 (8) 是特殊的,因为它只在少数情况下。例如:explicit

void process_all(std::span<const int> numbers);

std::span<int> get_range();

void foo() {
    auto r = get_range(); // ok, sizes match and qualifying conversion takes place
    process_all(r);
}

这是可能的,因为有一个从 到 的限定转换,因此我们可以转换为 。 这个用例很常见,因为 making 并不能确保元素的不可变性,只有 a 才能做到这一点。intconst intstd::span<int>std::span<const int>const std::span<T>std::span<const T>

这种合格的转化实际上可以是多个层次的,例如,我们可以:

  • 将 a 作为函数参数std::span<const int * const * const>
  • 将 a 传递给它std::span<int**>

但是,这不是此构造函数的唯一属性,(7) 也这样做。 你可能会问:“我们为什么不直接使用构造函数(7)呢?

template< class R >
explicit(extent != std::dynamic_extent)
constexpr span( R&& range ); // (7)

此构造函数适用于任何大小的连续范围,并且跨度为一个。 但是,对于静态范围,它始终是显式的,并且只有构造函数 (8) 允许在大小相等的静态范围之间进行隐式转换。例如:

#include <span>

void process_all(std::span<const int, 100> numbers);

std::span<int, 100> get_range();
std::span<int, 10> get_short_range();
std::span<int> get_dynamic_range();

void foo() {
    process_all(get_range());         // OK
    process_all(get_short_range());   // ill-formed, need explicit conversion
    process_all(get_dynamic_range()); // ill-formed, need explicit conversion
}

您给出的示例都使用显式转换,因此它们没有演示 (8) 的特殊之处,即它比其他构造函数在更少的情况下是有条件显式的。