【问题标题】:Where to use std::span?在哪里使用 std::span?
【发布时间】:2022-01-21 00:34:27
【问题描述】:

我想编写一个函数,它可以从其调用站点接受任何类型的连续缓冲区(例如std::arraystd::vector原始数组等)。我想出了两种方法。

方法#1:

void func( int* const buffer, const std::size_t expectedTokenCount );

这里,expectedTokenCount 是将插入到buffer 中的最大元素数。

方法#2:

void func( const std::span<int> buffer, const std::size_t expectedTokenCount );

在这种方法中,我认为我最好将函数编写为首先通过buffer.size( )检查buffer的大小并将其与expectedTokenCount进行比较以确保其容量大于或等于到expectedTokenCount 否则会引发某种异常。这是比第一种方法有效且安全的方法吗?哪一个更好?如果将向量传递给span 及其size 成员函数,其行为会发生变化还是会与数组相同?

【问题讨论】:

    标签: c++ c++20 copy-elision std-span


    【解决方案1】:

    在哪里使用 std::span?

    无论您在哪里使用指针和大小,都可以使用std::span 代替指针和大小。

    [#2] 是一个有效的...方法吗?

    当然。但是,您确实更改了指针的常量。你应该使用std::span&lt;const int&gt;

    哪个更好?

    各有各的用途。但在大多数情况下,传递两种尺寸是多余的

    std::span 的使用与使用两种尺寸的变化是正交的。您可以将#1 设为void(std::span&lt;const int&gt;),也可以将#2 设为void(int* const buffer, const std::size_t buffer_size, const std::size_t expectedTokenCount)

    使用std::span 通常是一种改进。

    【讨论】:

    • 那么您如何看待我的第二种方法和异常抛出部分?这样做可以吗?或者我应该例如在调用站点中编写一个 static_assert 来检查和比较 bufferexpectedTokenCount 的大小,然后再将它们传递给 func
    • @digito_evo:为什么需要将expectedTokenCountspansize 分开?
    • 或者更安全的方法!我可以将缓冲区传递给func,例如 { buffer.data(), expectedTokenCount }。这样更好吗?
    • @Nicol Bolas 好问题。本质上是为了在func 的正文中提高代码可读性,并使其更加万无一失
    • 如何使它更安全?它使它变得不那么简单,因为现在您有责任确保值相等。
    猜你喜欢
    • 2018-05-30
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 2018-05-18
    相关资源
    最近更新 更多