narrowing conversion from 'int' to 'double' and array initialization
Asked Answered
J

0

6

The following

int i = 0;
double d{i};

gives an error (in clang) or warning (in gcc) of a narrowing conversion from 'int' to 'double'. I found it amazing that this is really narrowing, at least until I saw narrowing conversion from unsigned to double.

My actual problem originates from a class that contains an array and provides a constructor for specifying the elements of the array, in the simplest way possible (forwarding):

template<typename T, size_t N>
struct A
{
    T a[N];

    template<typename... E>
    A(E&&... e) : a{std::forward<E>(e)...} { }
};

In this case, we have the following (live example):

int i = 0;
A<double, 2> x(i, 2);  // ERROR for both 'i' and '2'
double y[2]{i, 2};     // ERROR for 'i' only

where ERROR refers to narrowing conversion as discussed above. I suspect that all those errors boil down to the one mentioned at the beginning (double d{i};). Is this so? Otherwise, what is happening?

Anyhow, I would really like

A<double, 2> x(i, 2);

to work, exactly as

double x(i);

works. Unfortunately, I can only initialize the array using an initializer list, which also checks for narrowing conversions. I know one workaround is to make an explicit cast in the constructor:

template<typename... E>
A(E&&... e) : a{static_cast <T>(e)...} { }

or (thanks Marc)

template<typename... E>
A(E&&... e) : a{static_cast <T>(std::forward<E>(e))...} { }

but is this the "right" way? And is it the most efficient, when E is a "large" type?

Jempty answered 23/3, 2014 at 18:10 Comment(3)
Why remove forward? Try static_cast<T>(forward<E>(e)) with a type that prints something on copying, and notice that your cast is free.Vein
Yes, I was between those two options. I have my foo type exactly for such experiments (copying, moving, everything), and I will try now. Thanks. I'll also update it in the question.Jempty
@MarcGlisse Ok, I give an rvalue reference as input to the constructor, and it appears that it is only moved to the contained array, not copied (despite static_cast<T>). So is this the right way? Nothing else needed?Jempty

© 2022 - 2024 — McMap. All rights reserved.