How can you emplace_back the wrong type?

Viewed 181

I have a vector of doubles. But I had a typo

I intended to write this:

std::vector<double> timestamp;

But I wrote this instead:

std::vector<std::vector<double>> timestamp;

However, this compiles

timestamp.emplace_back(a_double_timestamp)

I am emplacing back a double into a std::vector<std::vector<double>>. double is not std::vector<double>

3 Answers

double is implicitly converted to size_type, acting as a parameter to the vector constructor :

explicit vector( size_type count );

Therefore, if you pass 2.3, the vector created has size static_cast<std::vector<double>::size_type>(2.3) == 2.

std::vector<double> v{2.3} also compiles without any warning.

Do you get any warnings? MSVC gives warning

'argument': conversion from 'double' to 'const unsigned __int64', possible loss of data

though GCC HEAD is silent.

What happens here is that explicit vector( size_type count ); constructor for your internal vector is called, with automatic conversion from double to size_type

I stepped through the code to see what was happening, and what I am seeing (in Visual Studio 2017 anyway) is that the following constructor is being called:

vector(_CRT_GUARDOVERFLOW const size_type _Count, const _Alloc& _Al = _Alloc())

... which seems to imply that the double was implicitly converted to a size_type (I used a double of 12.3 in my test, and the debugger is telling me _Count is 12). _Al has a default value, so the constructor matches.

Related