Domanda

I'm getting a strange error from Clang when compiling what should be a straightforward line of code.

This code produces an error:

size_t s = 5;
std::vector<double> bestScores{s, -1.0};

I'm simply trying to use constructor #2 to fill a new vector with five -1.0 values. The error I get is Non-constant expression cannot be narrowed from type 'size_type' (aka 'unsigned long') to 'double' in initializer list.

What is going on? This compiles fine:

std::vector<double> bestScores{5, -1.0};

Is it trying to use the initializer list constructor? I thought you needed two curly braces for that:

std::vector<double> bestScores{{5, -1.0}};
È stato utile?

Soluzione

The issue is that you are constructing the vector using a brace-enclosed initialization list. That favours the std::initializer_list<T> constructor when applicable. In this case, the size_t, -1.0 list is compatible with std::initializer_list<double>, so that constructor gets picked. You need to use the old-style, C++03 construction:

std::vector<double> bestScores(s, -1.0);

This is one of the gotchas of brace-enclosed initializers. They don't play well for certain standard library container instantiations. You have to remember that the std::initializer_list constructor will trump the others.

Altri suggerimenti

The issue is that when a class has an std::initializer_list constructor, it will prefer that when using the uniform initialization syntax if the arguments are convertible to the initializer_list's type (double in this case). See a detailed answer at programmers.stackexchange.com.

For now, your solution is to use the non-uniform syntax that uses parenthesis. This means it won't consider the std::initializer_list constructor, and do what you want in this case.

std::vector<double> bestScores(s, -1.0)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top