I have looked for this and found something here: Variable not printing on iteration but I'm not sure if that necessarily applies.
What I have going on is my program correctly prints all values when I call it like this:
for (int i = 0; i < SampleVec.Matchups().size(); ++i){
std::cout << SampleVec.Matchups()[i] << std::endl;
}
or when I call it like this:
std::vector<int> temp;
temp = SampleVec.Matchups();
for (std::vector<int>::const_iterator iter = temp.begin(); iter != temp.end(); iter++){
std::cout << *iter << std::endl;
}
but when I write it like this
for (std::vector<int>::const_iterator iter = SampleVec.Matchups().begin(); iter != SampleVec.Matchups().end(); iter++){
std::cout << *iter << std::endl;
}
the first two values show up as a 0 and the rest print correctly. In the link I posted they talk about stripping newlines from the input, but I don't know if that applies here or even how to do that. I can post full code if needed to run and see the functionality in action.
for (std::vector<int>::const_iterator iter = SampleVec.Matchups().begin(); iter != SampleVec.Matchups().end(); iter++){
std::cout << *iter << std::endl;
}
begin() returns the iterator of the beginning of a temporary std::vector returned by Matchups(). At the moment of using iter it's a dangling iterator because the temporary has been destroyed and thus you have Undefined Behaviour.
You have to store the result before trying to access it through an iterator like you do in example 2.
Related
So I've started learning vectors for the first time and wrote a simple program which goes like this:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> g1;
int n;
cout<<"enter values"<<endl;
do
{
cin>>n;
g1.push_back(n);
} while (n);
cout<<"Vector values are: "<<endl;
for(auto i=g1.begin(); i<g1.size();i++)
cout<<*i<<endl;
}
When I try executing it, an error shows up saying "type mismatch" at the g1.size() part. Why exactly does this happen? I used the auto keyword for the iterator involved and assumed there wouldn't be any problem?
That is the bad side of using auto. If you have no idea what the result of auto is, you get no idea why it is something totally different you expect!
std::vector::begin delivers a std::vector::iterator and you can't compare it against an size_type value which is a result of std::vector::size. This type is typically std::size_t
You have to compare against another iterator which is the representation of the end of the vector like:
for(auto i = g1.begin(); i != g1.end(); i++)
There are at least three ways to iterate through the contents of a vector.
You can use an index:
for (int i = 0; i < vec.size(); ++i)
std::cout << vec[i] << '\n';
You can use iterators:
for (auto it = vec.begin(); it != vec.end(); ++it)
std::cout << *it << '\n';
You can use a range-based for loop:
for (auto val : vec)
std::cout << Val <<'\n';
The latter two can be used with any container.
g1.begin() returns an iterator to the 1st element, whereas g1.size() returns the number of elements. You can't compare an iterator to a size, which is why you are getting the error. It has nothing to do with your use of auto, it has to do with you comparing 2 different things that are unrelated to each other.
You need to change your loop to compare your i iterator to the vector's end() iterator, eg:
for(auto i = g1.begin(); i != g1.end(); ++i)
cout << *i << endl;
Or, simply use a range-based for loop instead, which uses iterators internally:
for(auto i : g1)
cout << i << endl;
Otherwise, if you want to use size() then use indexes with the vector's operator[], instead of using iterators, eg:
for(size_t i = 0; i < g1.size(); ++i)
cout << g1[i] << endl;
According to the documentation, hashed index iterators remains valid when new elements are inserted into a multi_index. However when I attempted the following approach
auto& myIndex = myMultiIndex.get<0>();
auto range = myIndex.equal_range(x);
for (auto iter = range.first; iter != range.second; ++iter) {
myMultiIndex.emplace(someArgsRelatedToIter);
}
the range.first/range.second seem to become invalid: even though std::distance(range.first, range.second) == 1, the for loop actually gets executed twice. Am I somehow not using it correctly? Thanks!
When c++ libraries specify that iterators aren't invalidated by an operation it means that the iterators still point to the same element. For example in the following code:
std::list< int > l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
auto first = l.begin();
auto last = std::find(l.begin(), l.end(), 3);
std::cout << *first << std::endl;
std::cout << *last << std::endl;
1, 3 and 2 are printed. If we now insert some elements:
l.insert(last, 4);
l.insert(last, 5);
std::cout << *first << "\n";
std::cout << *last << "\n";
std::cout << std::distance(first, last) << "\n";
first and last are still valid and point to the same elements but the distance is now 4 so they point to a different range.
I'm trying to print elements of a vector of list pair in a hash-table program in C++.
If I use the C++11 auto it's working but if i use a iterator
for (vector<int>::iterator i = arr_Hash[i].begin(); i != arr_Hash[i].end(); ++i)
//for (auto index = arr_Hash[i].begin(); index != arr_Hash[i].end(); index++)
{
cout << i->second;
cout << " ";
}
Error list: https://i.imgur.com/rDejBGG.png
How can I use the iterator here?
vector<int>::iterator i = arr_Hash[i].begin()
You're reusing the variable i here. Call it something else.
std::cout << i->second;
i is a std::vector<int>::iterator. Dereferencing it gives you an int&, which has no second member. You probably just want std::cout << *i;
The iterator for arr_Hash[i] needs to be on the same type as the vector.
Namely, if the type of arr_Hash[i] is vector<pair<int,int>> then it's iterator needs to be vector<pair<int,int>>::iterator.
Howerver, you should Prefer a range-for-statement to a for-statement when there is a choice.
for (auto& e : arr_Hash[i])
cout << i->second << " ";
I am currently trying to create a vector containing function of a class .
Here is my code :
typedef leap::float64 (DataReader::*getFonction)();
std::vector<getFonction> vec;
std::vector<getFonction>::iterator it;
vec.push_back(&DataReader::getLa);
vec.push_back(&DataReader::getLon);
for(it = vec.begin(); it<vec.end(); it++)
std::cout << *it << std::endl;
The function "get ..." (not static ) returned values ββare stored on shared resources and already initialized.
But then , they return me only the values ββ'1'.
An idea?
When you dereference it and output it, you are just printing out a representation of the function pointer, which is being implicitly converted to bool and output as 1 because it is not null.
If you want to call the function and output the return value, you need to call it on an instance:
DataReader reader;
for(it = vec.begin(); it<vec.end(); it++)
//dereference it to get member function pointer and call it on reader
std::cout << (reader.*(*it))() << std::endl;
If you are using C++11, std::function may be better suited:
using getFunction = std::function<leap::float64(DataReader&)>;
std::vector<getFunction> vec;
std::vector<getFunction>::iterator it;
vec.emplace_back(&DataReader::getLa);
vec.emplace_back(&DataReader::getLon);
DataReader reader;
for(it = vec.begin(); it<vec.end(); it++)
std::cout << (*it)(reader) << std::endl;
i have a code like this....
std::vector<string>::iterator p;
p = find(v.begin(),v.end(),"asdasda");
cout << *p << endl;
if "asdasda" is not a part of the vector, p points to some garbage and cout gives a seg fault. what should be the if statement that would make the cout execute onlyif "asdasda" was found?
and also the position of "asdasda" in v.. like if we had earlier declared v[3] as "asdasda",
then how can i know from the find that v[3] is "asdasda"?
p doesn't point to "garbage", it simply becomes v.end() when the content is not found.
if (p != v.end()) {
std::cout << "v[" << (p - v.begin()) << "] = ";
std::cout << *p << std::endl;
}
If std::find doesn't find anything, the iterator is set to v.end() in this case.
if ( p != v.end() )
{
// iterator is good
}
Also note the general case of std::find.
Here's a typical definition of it:
namespace std {
template <class InputIterator, class T>
InputIterator find(InputIterator start,
InputIterator finish,
const T& value);
}
In case std::find fails, it will return the finish iterator because the search is [start, finish) and includes start but excludes finish.
Find returns the end iterator if it doesn't find the value you search.
You can avoid your error by adding if (p != v.end()) right before your display line.