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?
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.