C ++: What is the correct choice to bias to a std :: vector iterator?

I have a function that takes std::vector

twins and copies them into another vector, but at a certain offset (assuming there is enough 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);
}

      

The result is the C ++ 11 clang compiler -Weverything

centered on the part + dest_offset

:

Implicit conversion changes: signature "size_t" (aka "unsigned long") to "difference_type" (otherwise "long").

I am not sure how I should express the expression dest.begin() + dest_offset

in order to eliminate this warning. Passing the result to double *

not compile:

    std::copy(data, data + data_size, static_cast<double *>(dest.begin() + dest_offset));

      

Cannot be cast from type 'std :: __ 1 :: __ wrap_iter' to pointer type 'double *'.

I looked at using vector indexing and then took the address:

    std::copy(data, data + data_size, &dest[dest_offset]);

      

This seems to remove the warning in this case, but does not compile if I try to use the same pattern with the original vector, that is, with the offset associated with the first or second parameter 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 about implicit conversion to + offset

. Trying to use a postcode address might suggest:

    std::copy(&data[offset], data.end(), dest.begin());

      

Or another, but similar case:

    std::copy(data.begin(), &data[offset], dest.begin());

      

However, they both throw 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 proactive way to handle such offsets. What is the correct way to handle offsets in a vector and avoid such errors and warnings?

+3


source to share


2 answers


You can use several difference_type

to avoid this warning:

#include<vector>

using difference_type = std::vector<double>::difference_type;

void copy_stuff(const std::vector<double> & data,
                std::vector<double> & dest,
//                size_t dest_offset)
                difference_type dest_offset)
{
    std::copy(data.begin(), data.end(), dest.begin() + dest_offset);
}

      




It is now widely accepted [edit] that representing / using dimensions and some offsets as unsigned integer types was a mistake in the development of the standard library. Therefore, in my opinion, it is best not to follow this convention and use unsigned types from the standard library as soon as possible, instead of adapting your function to use unsigned types.

For example copy_stuff(a.begin(), a.end(), static_cast<difference_type>(other.size()) )

.

+4


source


I am not sure how I should express the expression dest.begin() + dest_offset

in order to eliminate this warning.

The warning just tells you what dest_offset

is expected to be of a type std::vector::difference_type

, but it is size_t

.

You can do the conversion explicitly to eliminate the warning (note that if the original value cannot be represented in difference_type

, the result is implementation-defined). eg.



dest.begin() + static_cast<std::vector<double>::difference_type>(dest_offset)

      

Or declare the parameter dest_offset

with a 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.

+3


source







All Articles