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?

Community
  • 1
  • 1
iavr
  • 7,547
  • 1
  • 18
  • 53
  • 1
    Why remove `forward`? Try `static_cast(forward(e))` with a type that prints something on copying, and notice that your cast is free. – Marc Glisse Mar 23 '14 at 18:18
  • 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. – iavr Mar 23 '14 at 18:24
  • 1
    @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`). So is this **the** right way? Nothing else needed? – iavr Mar 23 '14 at 18:45

0 Answers0