Reputation: 23
I am trying to iterate over a reference to a vector of strings inside a function. The code originally iterated over an internal copy of the vector but I would like to iterate over the original if possible. However, when I try to do so, I get type mismatch problems.
I tried to work with just portions of an iterator by setting and printing it, but I get similar type mismatching for both the initialization and printing with a %s format specifier. Inside gdb, printing the begin accessor works the same for the reference to the vector or a copy of that to its own vector.
Outside:
std::vector<std::string> foo;
foo.pushback('alpha');
foo.pushback('bravo');
func(foo);
Inside with copying:
void func(const std::vector<std::string> &bar){
std::vector<std::string> barcopy = bar;
for (std::vector<std::string>::iterator barIt = barcopy.begin(); barIt != barcopy.end(); barIt++){
//operations with the string inside barcopy
}
}
Inside without copying:
void func(const std::vector<std::string> &bar){
for (std::vector<std::string>::iterator barIt = bar.begin(); barIt != bar.end(); barIt++){
//operations with the string inside bar
}
}
I expected the reference to behave the same as the copy, but attempting this directly gets me the following when attempting to compile.
error: conversion from
'__gnu_cxx::__normal_iterator<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >'
to non-scalar type
'__gnu_cxx::__normal_iterator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >'
requested
What type does the begin accessor return when performed on a reference to a vector? How do I go about iterating over this reference without copying?
Upvotes: 2
Views: 410
Reputation: 25388
Because you are passing bar
as a const
ref, you need to change:
for (std::vector<std::string>::iterator barIt = bar.begin(); barIt != bar.end(); barIt++)
to:
for (std::vector<std::string>::const_iterator barIt = bar.cbegin(); barIt != bar.cend(); barIt++)
or, better still, use a ranged for loop, if all you want is to iterate through the elements in the vector:
for (auto &elem : bar)
Alternatively, change your function signature to void func(std::vector<std::string> &bar)
(without the const
). The ranged for loop will work in either case.
Upvotes: 7
Reputation: 18652
Notice that you are taking the parameter as a const
reference. The error is due to trying to take a non-const iterator from a const container. You could fix the error by changing your code to: (take note of the iterator type)
for (std::vector<std::string>::const_iterator barIt = bar.begin(); barIt != bar.end(); barIt++){
//operations with the string inside bar
}
Alternatively, you could use the auto
keyword which will deduce the correct iterator type:
for (auto barIt = bar.begin(); barIt != bar.end(); barIt++){
//operations with the string inside bar
}
Upvotes: 3