views:

98

answers:

5

Is it safe to do this?

double darray[10];
vector<float> fvector;
fvector.insert(fvector.begin(), darray, darray + 10);  // double to float conversion

// now work with fvector

VS2008 gives me a warning about the double to float conversion. How do I get rid of this warning? I don't think it makes sense to cast darray to float* as that would change the step size (stride) of the pointer.

Update: I know what the warning indicates. But unlike the "afloat = adouble;" scenario where I can easily apply a cast, I am unable to eliminate the warning in this case.

Edit: I've edited the code so that darray is no longer a function argument. Thanks to all those of you who pointed it out.

A: 

In my opinion there is an other problem. The vector has not enough space...

Why? A `vector<>` grows automatically to have as much space as it needs.
Gorpik
The `.insert` family of methods will allocate extra space if required. After the call the vector size will have grown by `std::distance(darray,darray+10)`, i.e. 10.
David Rodríguez - dribeas
Sorry. It's hot in Germany today. :-) Was thinking of std::copy.
+1  A: 

The warning is about loss of significant digits without an explicit cast. You should get the same warning for

double d = 1.0;
float f = d;

You can disable the warning for the assignment (see #pragma warning in MSDN).

peterchen
If the compiler is smart, it should know that 1.0 is represented exactly in doubles and also floats. With 0.2 however, which cannot be represented exactly, it should warn.
Peter G.
I expect the optimizer to folde the two assignments into one (unless d is used later). However, I do expect capabilities of the optimizer to **not** affect compiler diagnostics. if there is a warning, I want it for 1.0 and for 0.2.
peterchen
+3  A: 

You get the warning because you are losing precision in the double to float conversion, that's all. Assuming that you really need fvector to be a vector<float> and not a vector<double>, it is clear that you can live with this precision loss, so the warning is not important.

Gorpik
+1 Yes. Either disable the warning or use `std::transform` and provide explicit cast in transform function.
Tomek Szpakowicz
A: 

VS2008 gives me a warning about the double to float conversion. How do I get rid of this warning?

void some_function(double *darray){
    vector<double> fvector;
    fvector.insert(fvector.begin(), darray, darray + 10);
}

Or

void some_function(float *darray){
    vector<float> fvector;
    fvector.insert(fvector.begin(), darray, darray + 10);
}

Or overload your function with both variants, or make it a template

template<typename RandomAccessIterator>
void some_function(RandomAccessIterator it){
    typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
    vector<value_type> fvector(it, it + 10);
}

Of course, it's not a good idea to assume a fixed 10. Notice that neither your original code is safe, because the 10 in the parameter list of your function has no meaning. It's simply ignored. So better document it clearly, that the iterator or pointer needs to provide access to sufficiently many values.

Johannes Schaub - litb
+3  A: 

Use std::transform() this allows you to provide a conversion method.
Then you just need a conversion method that does not generate a warning:

#include <vector>
#include <algorithm>
#include <iterator>

struct CastToFloat
{
    float operator()(double value) const { return static_cast<float>(value);}
};

int main()
{
    double  data[]  = { 1, 2,3,4,5,6,7,8,9,10};
    std::vector<float>  fl;


    std::transform(data, data+10,
                    std::back_inserter(fl),
                    CastToFloat());
}
Martin York