2

I want to write a function that can accept any type of contiguous buffer (e.g. std::array, std::vector, raw array, etc) from its call site. I have come up with two methods.

Method #1:

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

Here, expectedTokenCount is the maximum number of elements that will be inserted into the buffer.

Method #2:

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

In this approach, I think that I better write the function in a way that first checks the size of the buffer via buffer.size( ) and compares it with expectedTokenCount to make sure that its capacity is greater than or equal to expectedTokenCount otherwise it throws some kind of exception. Is this a valid and safer method than the 1st method? Which one is better? Will the behavior of span and its size member function change if a vector is passed to it or will it be the same as for array?

digito_evo
  • 3,216
  • 2
  • 14
  • 42

1 Answers1

4

Where to use std::span?

Where-ever you would have otherwise used a pointer and a size, you can use std::span instead of the pointer and the size.

Is [#2] a valid ... method?

Sure. You did however change the constness of the pointer. You should use std::span<const int>.

Which one is better?

Each have their uses. But in most cases passing two sizes is redundant

The use of std::span is orthogonal to the change of using two sizes. You can do #1 as void(std::span<const int>) and you can do #2 as void(int* const buffer, const std::size_t buffer_size, const std::size_t expectedTokenCount).

Using std::span is generally an improvement.

康桓瑋
  • 33,481
  • 5
  • 40
  • 90
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • So what do you think about my 2nd method and the exception throwing part? Is it ok to do that? Or should I for example just write a static_assert in the call site to check and compare the size of the `buffer` and `expectedTokenCount` before passing them to the `func`? – digito_evo Dec 18 '21 at 14:18
  • 2
    @digito_evo: Why do you need `expectedTokenCount` separate from the `span`'s `size`? – Nicol Bolas Dec 18 '21 at 14:20
  • Or maybe an even safer way! I can pass the buffer to `func` like { buffer.data(), expectedTokenCount }. Is this better? – digito_evo Dec 18 '21 at 14:20
  • @Nicol Bolas Good question. Essentially for better code readability inside the `func`'s body and also making it a bit more *foolproof*. – digito_evo Dec 18 '21 at 14:23
  • 2
    How does that make it more foolproof? It makes it less foolproof as now you have the responsibility of ensuring that the values are equal. – Passerby Dec 18 '21 at 14:36