'How do you use std::distance in a range-based loop?
This is my code that won't compile:
for( auto occurances : occ ){
if( occurances == 1 )
cout << distance( occ.begin(), occurances )
}
It gave me the following error:
candidate template ignored: deduced conflicting types for parameter '_InputIter'
('std::__wrap_iter<int *>' vs. 'int')
This is the fifth time I encountered this error. Each time, after a bit of research and frustration, I just give up and use the basic for-loop. The problem here is that I am too lazy to write the basic for-loop like:
for( size_t occurances = 0; occurances < occ.size(); occurances++ ){
if( occ[ occurances ] == 1 )
// do something with size_t occurances
}
I tried to insert a * infront of occ.begin() ( i don't really understand pointers ). The error changed to this:
candidate template ignored: substitution failure [with _InputIter = int]: no type
named 'difference_type' in 'std::iterator_traits<int>'
distance(_InputIter __first, _InputIter __last)
How do I fix this? Thanks everyone for answers, really apreciate it. Sorry if this is a duplicate question, I really couln't find the answer.
Solution 1:[1]
You could count the iterations round the loop yourself:
size_t loop_count = 0;
for( auto occurances : occ ){
if( occurances == 1 )
cout << loop_count;
++loop_count;
}
But that's really no easier than just coding the for loop explicitly, and you might forget to bump the counter.
OK, since the OP is interested in doing this for a vector, here's a solution that works for std::vector and std::string ONLY. It works because, for these containers, operator[] returns a reference to the element or character corresponding to the index you pass in, and it is legal (and, here, useful) to take the address of that reference.
Since these containers both guarantee contiguous storage these days, you can just use the difference between two addresses obtained in this way to get what you want.
Here's a simple example:
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::string s = "abcde";
std::vector <int> v ( { 100, 101, 102, 103, 104 } );
for (const auto &c : s)
{
if (c == 'c')
std::cout << &c - &s [0] << "\n";
}
for (const auto &e : v)
{
if (e == 103)
std::cout << &e - &v [0] << "\n";
}
}
Output:
2
3
Note that, as mentioned in the comments, you need to use auto &, rather than just auto, because auto passes copies into the loop and that would wreck the whole idea.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
