I have an issue in that I cannot use a certain constructor with an array initializer when using VS2017 (C++14, C++17 and ISO latest).
I get an C2397 conversion from 'double' to 'unsigned int' requires a narrowing conversion
error when it should be invoking the constructor with a container populated with a single element.
#include <vector>
class obj
{
public:
obj(const std::vector<double>& values, unsigned int stride)
: values_(values), stride_(stride)
{
}
obj(unsigned int m, unsigned int n)
: stride_(n)
{
}
private:
unsigned int stride_;
std::vector<double> values_;
};
int main(int argc, char** argv)
{
obj m(1, 1); // correct constructor called.
obj mm({ 42.0 }, 1); // Error C2397
return 0;
}
I can fix this by explicitly declaraing the container...
obj mm(std::vector<double>({ 42.0 }), 1);
Or initializing the container with more than one item...
obj mm({ 42.0, 12.0 }, 1);
The latter obviously being of no use, and the former being slightly annoying as it's a corner case for containers with a single item (albeit not the end of the world). I thought this might be problematic for doubles only (having no literal declaration), however it even occurs for floats when initializing them with literals too. i.e container is std::vector<float>
, the following line still errors with C2397.
obj mm({ 42.0f }, 1);
I don't tend to believe in compiler bugs myself having not come across many (although they obviously exist), however I can't help but think this may be one, or if not, is there any mention in the standard how to deal with this situation. Ideally I would like to be able to use the array initializer without explicitly declaring the container type as I can when more than one item exists in the container. Is this possible?
Using {{
and }}
is the fix in all cases
obj mm({{ 42.0 }}, 1);
and
obj mm({{ 42.0, 12.0 }}, 1);
Although of course there is no ambiguity in the second case (the use of single braces is exploiting brace-elision).
This question affords a good introduction to the topic: Brace elision in std::array initialization
Do you mean the following
obj mm({ 1, 42.0 }, 1);
or the following
obj mm({ { 42.0 } }, 1);
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