jcai
jcai

Reputation: 3593

How to use an explicit cast to suppress this warning?

The following code:

#include <cstdint>
#include <vector>
#include <boost/range/irange.hpp>

int main() {
    int64_t first = 0, last = 10;
    std::vector<double> result = boost::copy_range<std::vector<double>>(boost::irange(first, last));
}

generates the warning (and 100+ lines of templated call stack trace):

1>C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xmemory0(600):
warning C4244: 'initializing' : conversion from 'unsigned __int64' to 'double', possible loss of data

I want to tell the compiler that I don't care that my int64_t are being converted to double. I also do not want to use a 32-bit int instead. I would usually use static_cast<double>(my64BitInt) to solve this, but that won't work for a range. Right now I'm resorting to compiler pragmas to suppress the warning but that's not ideal.

Edit: Here's a pastebin with the full compiler output.

Upvotes: 5

Views: 2246

Answers (2)

Phil
Phil

Reputation: 6164

I think you will need to use std::transform rather than the boost copy_range. Also, I much prefer using the boost numeric cast over the built-in static_cast.

Here is a working example:

template <class DST, class SRC>
struct Convert
{
    DST operator()(SRC s) { return boost::numeric_cast<DST>(s); }
};

int main(int argc, const char* argv[])
{
    int64_t first = 0, last = 10;
    auto my_range = boost::irange(first, last);
    std::vector<double> result(my_range.size());
    std::transform(my_range.begin(), my_range.end(), result.begin(), Convert<double, int64_t>());

    std::cout << "result: ";
    std::copy(result.begin(), result.end(), std::ostream_iterator<double>(std::cout, ", "));

}

The above code uses transform with the functor Convert. If you prefer a lambda, this works (and is more succinct) too:

std::transform(my_range.begin(), my_range.end(), result.begin(), 
               [](int64_t ival) {
                   return boost::numeric_cast<double>(ival);
               }
               );

EDIT Add iota variant too

As sehe points out, to generate a vector of doubles in the range [0, 10), you can use the std library iota (from #include numeric) function. Here is a complete (and much shorter) iota example that does not need boost:

std::vector<double> result(10);
std::iota(result.begin(), result.end(), 0.0);
std::cout << "result: ";
std::copy(result.begin(), result.end(), std::ostream_iterator<double>(std::cout, ", "));

Thank you, sehe, for pointing it out.

Upvotes: 2

sehe
sehe

Reputation: 393114

what Phil said;

However in this case, you could do much simpler using the iota algorithm:

#include <vector>
#include <boost/range/algorithm_ext.hpp>

int main() {
    std::vector<double> result(10);
    boost::iota(result, 0);
}

Upvotes: 2

Related Questions