#include <boost/type_index.hpp>
#include <iostream>
#include <vector>
int main()
{
std::vector v{2, 3.14};
std::cout << boost::typeindex::type_id_with_cvr<decltype(v)>().pretty_name() << '\n';
std::cout << "size: " << v.size() << '\n';
for (auto x : v)
std::cout << "- " << x << '\n';
}
The output is:
std::vector<double, std::allocator<double> >
size: 2
- 2
- 3.14
std::vector instantiation uses auto-type-deduction (CTAD).
Apparently, the initializer_list constructor is used (checked), but why does it accept both an int and a double and still deduces the type as vector<double> ?
If I increase the number of elements (while mixing int and double), compilation fails.
The same result with gcc and clang
$ g++ --version
g++ (GCC) 13.0.1 20230401 (Red Hat 13.0.1-0)
$ clang++ --version
clang version 16.0.1 (Fedora 16.0.1-1.fc38)
There are two instances of overload resolution happening here. The first is to deduce the template argument. Since the two types in the init-list are different, the size+value constructor (or more formally, the deduction guide generated from said constructor) is picked here, deducing the type to be
double.Then overload resolution runs again to create the object. With the type now known as
double, the list constructor is now valid, and thus used to initialize the object.