Usage of std::span with non-iterable type

97 views Asked by At

I was trying out some C++20 when I stumbled upon a rather strange (at least to me) situation. I was expecting the following code to not work with one of my examples (I've specified the expected behavior with comments), but it did work, and I want to know why. Here's the code snippet:

#include <iostream>
#include <span>

using namespace std;

struct simpleType
{
    simpleType(const int id) : id(id) {}

    int id;
};

template <typename IterableType>
void print(const IterableType& sequenceToPrint)
{
    cout << "[ ";

    for(const auto& element : sequenceToPrint)
    {
        cout << element.id << " ";
    }

    cout << "]" << endl;
}

void test()
{
    simpleType arr [] {1,2,3,4,5};
    span arrSpan {arr};

    // This should work
    print(arrSpan); // prints [ 1 2 3 4 5]
    // This should not
    print(arr); // prints [ 1 2 3 4 5 ] as well
}

int main()
{
    test();
}

I wasn't expecting it to work in both situations because, from my understanding, my templated print function should only work with iterable types because of the range based for loop. What am I missing?

2

There are 2 answers

0
H.S. On BEST ANSWER

For this

print(arrSpan)

the implicit instantiation of template would be:

void print<std::span<simpleType, 5> >(const std::span<simpleType, 5>& sequenceToPrint)

and for this

print(arr)

the implicit instantiation of template would be:

void print<simpleType[5]>(const simpleType (&sequenceToPrint)[5])

Both are iterable.

1
Ahmed AEK On

the first loop on an array works because c++ can produce a range based for loop for arrays if it knows its size at compile time and the template is deduced as <simpleType[5]>

the template will fail if you are passing simpleType* as the array size is not known at compile time.

std::span can also be constructed from an array if the array size is known at compile time, and std::span provides the needed begin and end methods that return an iterator type which are needed for a range based for loop.