jeudi 22 mars 2018

Why does std::vector

I have a question concerning the following c++ program:

#include <vector>
#include <iostream>

int main(){
    unsigned int i{5};
    std::vector<double> v{i};
    for(auto d : v){
            std::cout << d << std::endl;
    }
    return 0;
}

g++ version 4.9.3 and g++ version 5.4 compile and generate the warning:

test.cpp:6:25: warning: narrowing conversion of ‘i’ from ‘int’ to ‘double’ inside { } [-Wnarrowing]
std::vector<double> v{i};

which I can understand, as according to the specification, the compiler wants to use the initializer list constructor of std::vector :

When objects of non-aggregate class type T are list-initialized (8.5.4), overload resolution selects the constructor in two phases:

— Initially, the candidate functions are the initializer-list constructors (8.5.4) of the class T and the argument list consists of the initializer list as a single argument.

— If no viable initializer-list constructor is found, overload resolution is performed again, where the candidate functions are all the constructors of the class T and the argument list consists of the elements of the initializer list.

But what I can not understand is that clang version 3.8 fails to compile the program, with the same error as the warning above. I would expect that in this case the initializer-list constructor is not viable (at least clang rejects it) and the "intended" constructor of std::vector should be used instead.

My question: Narrowing conversions are syntax errors in the program and hence (in my understanding) the constructor of std::vector should be used that creates a std::vector of size 5. So why are the compilers ignoring the constructor that would lead to a valid program?

Thank you in advance!

Aucun commentaire:

Enregistrer un commentaire