Reputation: 3593
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
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
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