强制gsl::as_span到return一个gsl::span<const T>?
Force gsl::as_span to return a gsl::span<const T>?
给定以下函数,采用:只读 浮动范围(动态或任何静态大小):
template <long N> void foobar(gsl::span<const float, N> x);
假设我有一个vector<float>
。将其作为参数传递是行不通的,但使用 gsl::as_span
:
也行不通
std::vector<float> v = {1, 2, 3};
foobar(gsl::as_span(v));
以上不编译。显然 gsl::as_span()
return 是 gsl::span<float>
。除了不理解为什么隐式转换为 gsl::span<const float>
是不可能的,有没有办法强制 gsl::as_span()
到 return 一个只读跨度?
在您链接到的 github 页面上搜索 GSL/span.h,我发现以下 as_span
的重载,我相信是这里调用的那个:
template <typename Cont>
constexpr auto as_span(Cont& arr) -> std::enable_if_t<
!details::is_span<std::decay_t<Cont>>::value,
span<std::remove_reference_t<decltype(arr.size(), *arr.data())>, dynamic_range>>
{
Expects(arr.size() < PTRDIFF_MAX);
return {arr.data(), narrow_cast<std::ptrdiff_t>(arr.size())};
}
这里有很多东西需要消化,但特别是此函数的 return 类型归结为 span<std::remove_reference<decltype(*arr.data())>, ...>
。对于给定的 vector<float>
给出 span<float,...>
因为 decltype(*arr.data())
是 float &
。我相信以下内容应该有效:
const auto & cv = v;
foobar(as_span(cv));
但不幸的是我无法亲自测试。让我知道这是否有效。
as_span
不再是 MS/GSL 的一部分,可能是因为 gsl::span
最近与 std::span
对齐——您现在可以将其与 C++20 一起使用。
您可以使用 std::as_const
获取一个 const 容器并从中创建一个 gsl::span
(或者在您的情况下使用 gsl::as_span
)。
foobar(gsl::span<const float>(std::as_const(v)));
请注意,根据 foobar
的实施,无需对其进行模板化。你也可以只写
void foobar(gsl::span<const float> x);
默认情况下,跨度的长度为 dynamic_extent
,因此可以接受任何长度的跨度。当然,在编译时你不会有可用的长度。
给定以下函数,采用:只读 浮动范围(动态或任何静态大小):
template <long N> void foobar(gsl::span<const float, N> x);
假设我有一个vector<float>
。将其作为参数传递是行不通的,但使用 gsl::as_span
:
std::vector<float> v = {1, 2, 3};
foobar(gsl::as_span(v));
以上不编译。显然 gsl::as_span()
return 是 gsl::span<float>
。除了不理解为什么隐式转换为 gsl::span<const float>
是不可能的,有没有办法强制 gsl::as_span()
到 return 一个只读跨度?
在您链接到的 github 页面上搜索 GSL/span.h,我发现以下 as_span
的重载,我相信是这里调用的那个:
template <typename Cont>
constexpr auto as_span(Cont& arr) -> std::enable_if_t<
!details::is_span<std::decay_t<Cont>>::value,
span<std::remove_reference_t<decltype(arr.size(), *arr.data())>, dynamic_range>>
{
Expects(arr.size() < PTRDIFF_MAX);
return {arr.data(), narrow_cast<std::ptrdiff_t>(arr.size())};
}
这里有很多东西需要消化,但特别是此函数的 return 类型归结为 span<std::remove_reference<decltype(*arr.data())>, ...>
。对于给定的 vector<float>
给出 span<float,...>
因为 decltype(*arr.data())
是 float &
。我相信以下内容应该有效:
const auto & cv = v;
foobar(as_span(cv));
但不幸的是我无法亲自测试。让我知道这是否有效。
as_span
不再是 MS/GSL 的一部分,可能是因为 gsl::span
最近与 std::span
对齐——您现在可以将其与 C++20 一起使用。
您可以使用 std::as_const
获取一个 const 容器并从中创建一个 gsl::span
(或者在您的情况下使用 gsl::as_span
)。
foobar(gsl::span<const float>(std::as_const(v)));
请注意,根据 foobar
的实施,无需对其进行模板化。你也可以只写
void foobar(gsl::span<const float> x);
默认情况下,跨度的长度为 dynamic_extent
,因此可以接受任何长度的跨度。当然,在编译时你不会有可用的长度。