Consider the following code snippet:
#include <vector>
#include <ranges>
#include <iostream>
struct A
{
};
struct B
{
B(void *) {};
};
template<class T, class R>
std::vector<T> foo(R &&range)
{
return std::vector<T> {
std::ranges::begin(range),
std::ranges::end(range)
};
}
int main()
{
std::cout << foo<A>(std::views::empty<A>).size() << "\n";
std::cout << foo<B>(std::views::empty<B>).size() << "\n";
}
It correctly prints 0 on the first line and incorrectly prints 2 on the second line on GCC 11.2 (https://godbolt.org/z/s6aoTGbr4) and MSVC 19.30.30705 (Visual Studio 2022 17.0).
Apparently in the second case std::views::empty view produces iterators that causes constructor taking initializer list to be selected.
Changing std::vector<T> { ... } to std::vector<T> ( ... ) fixes this, but I wonder if it is actually a bug in implementation (or even definition) of the empty view?
Btype is constructible from pointers so it makes sense that this can happen.