Search code examples
c++pointersc++20

Construct static extent of std::span from `{pointer, length}`


Preface

Given a char *p pointer pointing to a buffer with given size_t length. Caller will guarantee the buffer is valid.

I want to use void spanStatic(std::span<char,8> s) to modify the buffer. I tried to use spanStatic({p, length}) where length is larger than 8. The compilation failed. I presum compiler may not deduce initializer list to span<char,8>... but with span<char,dynamic_extent>?

Note: I tend to use static extent. Since the lengh I want to modified is decided in compile time and the issue may be found in compile time as well.

Question:

Is there a shorter way to construct a temporary span instead of using spanStatic(std::span<char, 8>(p, length))?

Live demo

#include <fmt/format.h>
#include <span>

constexpr const char MAGIC_PATTERN[] = "\xBA""\xAD""\xF0""\x0D""\xDE""\xAD""\xBE""\xEF";
constexpr static size_t LEN = sizeof(MAGIC_PATTERN) - 1;

constexpr static std::span<const char, LEN> magic(MAGIC_PATTERN, LEN);

void spanDynamic(std::span<char> s){
    std::copy(magic.begin(), magic.end(), s.begin());
}
void spanStatic(std::span<char,LEN> s){
    std::copy(magic.begin(), magic.end(), s.begin());
}
int main()
{
    char data[] = "hello world";

    // Mimic a valid pointer + length, where length must be larger than LEN
    char* p = data;
    spanDynamic({p, LEN});
    // spanStatic({p, LEN}); // <--failed
}

Edit:

Thanks for Nicol Bolas's answer and HarryLeong's comment.
It's intended to have explicit constructors. My final solution is using MySpan = std::span<char, 8>.


This question is different from Why can't I construct a gsl::span with a brace-enclosed initializer list which is constructing a temporary std::array to a span.


Solution

  • span was explicitly designed to not allow you to do that. If you're using a span with a compile-time fixed size, the type was written so that you have to spell out that fixed size when you try to create one. That way, it's abundantly clear to everyone what the actual size is, even though you passed length.