This is a rather complicated question, and perhaps VisualStudio is right, and Como is wrong (it seems very hard to believe).
The standard, if you read by word, defines this vector constructor in terms of the copy constructor (see the citation), and this literally means that the object obtained by dereferencing the iterator must first be converted to type T, and then the constructor must be called. At this point, the code should not compile with the explicit constructor.
It seems reasonable to expect that the implementation, on the other hand, will directly call the constructor, which takes the dereferenced iterator as an argument, in which case the constructor call will be explicit and therefore the code must be compiled. This will contradict the exact wording in the quotation below, since the copy constructor is defined for a given type T as a constructor that accepts the only possible permanent reference to an object of type T.
I can’t come up with a reasonable argument, so as not to use Comow’s approach, and I think (this is just a personal opinion) that the wording in the standard regarding the complexity of a vector constructor should probably be adjusted as only N needs to refer to the corresponding constructor T, where necessary, should be defined as a constructor that matches the call T( *first ) (ie, either a constructor that takes InputIterator::value_type (by value or may permalink) or copy constructor T n follows an implicit conversion from InputIterator::value_type in T.
23.2.4.1 [lib.vector.cons] / 1
Difficulty: the vector of the constructor template (InputIterator first InputIterator) does only N invokes the copy constructor T (where N is the distance between the first and last) and redistribution if the iterators are the first and last of the forward, bidirectional or random access categories. This makes the order of N invokes the copy constructor T and the order of registration of N redistributions if they simply enter iterators.
I would like to know how the VS compiler behaves:
struct T1; struct T2 { operator T1 (); }; struct T1 { T1( T2 const & ) { std::cout << "T1(T2)" << std::endl; } }; T2::operator T1() { std::cout << "T2::operator T1" << std::endl; return T1(*this); } int main() { std::vector<T2> v2; v2.push_back( T2() ); std::vector<T1> v1( v2.begin(), v2.end() ); }
With g ++, the result is that T2::operator T1 not called, and elements from v1 are built directly from elements in v2 . I would suggest that with VS, the compiler would use T2::operator T1 to convert from each element in v2 to T1 element, and then call the copy constructor. This is true?