I have a function that takes a std::vector
of doubles, and copies them to another vector, but at a particular offset (assume there is sufficient space):
void copy_stuff(const std::vector<double> & data,
std::vector<double> & dest,
size_t dest_offset) {
std::copy(data.begin(), data.end(), dest.begin() + dest_offset);
}
This results in a C++11 clang compiler -Weverything
warning centered on the + dest_offset
part:
Implicit conversion changes signedness: 'size_t' (aka 'unsigned long') to 'difference_type' (aka 'long').
I'm not sure how I should cast the expression dest.begin() + dest_offset
in order to eliminate this warning. Casting the result to a double *
does not compile:
std::copy(data, data + data_size, static_cast<double *>(dest.begin() + dest_offset));
Cannot cast from type 'std::__1::__wrap_iter' to pointer type 'double *'.
I had considered using vector indexing and then taking the address:
std::copy(data, data + data_size, &dest[dest_offset]);
This seems to eliminate the warning in this case, but doesn't compile if I try to use the same pattern with the source vector, i.e. with an offset involved with the first or second parameter of std::copy
. For example:
static void copy_stuff_differently(const std::vector<double> & data,
std::vector<double> & dest,
size_t offset) {
std::copy(data.begin() + offset, data.end(), dest.begin());
}
Gives the same original warning of implicit conversion on the + offset
. Attempting to use the address-of-index might suggest:
std::copy(&data[offset], data.end(), dest.begin());
Or a different but similar case:
std::copy(data.begin(), &data[offset], dest.begin());
However both cause a similar error:
test.cpp:8:3: error: no matching function for call to 'copy'
std::copy(&data[offset], data.end(), dest.begin());
^~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iterator:1286:48: note:
candidate template ignored: deduced conflicting types for parameter '_Ip' ('const double *' vs.
'std::__1::__wrap_iter<const double *>')
template <class _Ip, class _Op> friend _Op copy(_Ip, _Ip, _Op);
^
I'm looking for a consistent and warning-free way to handle such offsets. What is the right way to handle offsets into a vector and avoid such errors and warnings?
Input iterators are one of the five main types of iterators present in C++ Standard Library, others being Output iterators, Forward iterator, Bidirectional iterator and Random – access iterators.
If two unrelated iterators (including pointers) are subtracted, the operation results in undefined behavior [ISO/IEC 14882-2014]. Do not subtract two iterators (including pointers) unless both point into the same container or one past the end of the same container.
std::distance returns a signed value. I am assuming you are trying to get the distance in such a way that -2 AND 2 would be considered as 2 . The abs function gives you the absolute value which means that whatever the sign of the input, you always get a positive value back.
An iterator is used to point to the memory address of the STL container classes. For better understanding, you can relate them with a pointer, to some extent. Iterators act as a bridge that connects algorithms to STL containers and allows the modifications of the data present inside the container.
I'm not sure how I should cast the expression
dest.begin() + dest_offset
in order to eliminate this warning.
The warning is just telling you that dest_offset
is expected to be of the type std::vector::difference_type
, but it's size_t
.
You can do the conversion explicitly to eliminate the warning (note that if the source value can't be represented in difference_type
the result is implementation-defined). e.g.
dest.begin() + static_cast<std::vector<double>::difference_type>(dest_offset)
Or declare the parameter dest_offset
with the type difference_type
from the beginning.
Note that std::vector::difference_type is a signed integer type (usually std::ptrdiff_t), which is different from size_t; which is an unsigned integer type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With