I am grading some homework C++ code and a student used a non-standard constructor for a vector of vectors:
vector<vector<double> > A(rows, cols);
where rows
and cols
are unsigned integers. The way we taught it in class is
vector<vector<double> > A(rows, vector<double>(cols));
following the fill constructor (2 in http://www.cplusplus.com/reference/vector/vector/vector/)
I am using a batch file to compile all students codes with the command line
cl /O2 /EHsc /Tp <filename>
and this command threw this error at the student line mentioned above:
error C2664: 'std::vector<std::vector<double,std::allocator<_Ty>>,std::allocator<std::vector<_Ty,std::allocator<_Ty>>>>::vector(std::initializer_list<std::vector<_Ty,std::allocator<_Ty>>>,const std::allocator<std::vector<_Ty,std::allocator<_Ty>>> &)' : cannot convert argument 2 from 'unsigned int' to 'const std::vector<double,std::allocator<_Ty>> &'
with
[
_Ty=double
]
Reason: cannot convert from 'unsigned int' to 'const std::vector<double,std::allocator<_Ty>>'
with
[
_Ty=double
]
Constructor for class 'std::vector<double,std::allocator<_Ty>>' is declared 'explicit'
with
[
_Ty=double
]
But when I create a project and build it with the default parameters of MSVC 2010 it does not throw neither a warning nor an error there.
I am trying to learn what compiler option is responsible for allowing it go through without a warning in the IDE, and what I would switch it off.
I tried finding an answer in http://msdn.microsoft.com/en-us/library/2tb15w2z(v=vs.100).aspx, but I couldn't an answer.
EDIT: I think this might be helpful to others: thanks to the comments I understand now the constructor called in the IDE is the range constructor (#3 in the link above).
Here's my particular question: both methods use the same compiler with different options (one the default from the IDE, the other one is stated above). The batch file throws an error, the IDE doesn't. I need help identifying what to change in the IDE's command line arguments so that it throws the error.
UPDATE: I included the error message.
UPDATE 2: It turns out the script was being run in a computer with MSVC 2013 and that was the difference
Actually:
std::vector<std::vector<double> a( rows, columns );
is legal, or at least it was legal until C++11. It wasn't intentionally legal, but the way the standard was worded, a compiler was required to accept it. (I think C++11 fixed this. Although it did so a bit too late, since doing so breaks previously legal code.)
The rule is (or was) simple, if overload resolution on the
constructor results in the constructor
<template Iter>std::vector::vector( Iter begin, Iter end )
being chosen, and Iter
deduces to an integral type, the code
must behave as if
std::vector::vector( static_cast<size_type>( begin ), static_cast<value_type>( end ) )
were called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With