A question about the std::set<>::iterator

R

Renzr

I have a problem about the std::set<>iterator. After finding a term in
the std::set<>, i want to know the distance from
the current term to the begin(). But i have got a error. Please offer
me help, thank you. I am a freshman about the STL. The following is
the code.
#include <set>
#include <iostream>
#include <vector>
int main()
{
std::set<unsigned int> a;
a.insert(1); a.insert(2); a.insert(3); a.insert(4); a.insert(5);
std::set<unsigned int> b;
b.insert(6); b.insert(7); b.insert(8); b.insert(9); b.insert(10);
std::vector<std::set<unsigned int> > ab(2);
ab[0]= a; ab[1]=b;
{
const unsigned int i=0, j=5;
std::set<unsigned int>::iterator it=ab.find(5);
if(it!=ab.end()) std::cout<<it-ab.begin()<<std::endl;
else { std::cout<"There is no:"<<j<<" in "<<i<<std::endl;
}
}
return 0;
}

This is the error:
error: no match for 'operator-' in 'it - (+(&ab)->std::vector<_Tp,
_Alloc>::eek:perator[] [with _Tp = std::set<unsigned int,
std::less<unsigned int>, std::allocator<unsigned int> >, _Alloc =
std::allocator<std::set<unsigned int, std::less<unsigned int>,
std::allocator<unsigned int> > >](0u))->std::set<_Key, _Compare,
_Alloc>::begin [with _Key = unsigned int, _Compare =
std::less<unsigned int>, _Alloc = std::allocator<unsigned int>]()'
/usr/lib/gcc/i386-redhat-linux/3.4.2/../../../../include/c++/3.4.2/
bits/stl_bvector.h:180: note: candidates are: ptrdiff_t std::eek:perator-
(const std::_Bit_iterator_base&, const std::_Bit_iterator_base&)
 
V

Victor Bazarov

Renzr said:
I have a problem about the std::set<>iterator. After finding a term in
the std::set<>, i want to know the distance from
the current term to the begin(). But i have got a error. Please offer
me help, thank you. I am a freshman about the STL. The following is
the code.
#include <set>
#include <iostream>
#include <vector>
int main()
{
std::set<unsigned int> a;
a.insert(1); a.insert(2); a.insert(3); a.insert(4); a.insert(5);
std::set<unsigned int> b;
b.insert(6); b.insert(7); b.insert(8); b.insert(9); b.insert(10);
std::vector<std::set<unsigned int> > ab(2);
ab[0]= a; ab[1]=b;
{
const unsigned int i=0, j=5;
std::set<unsigned int>::iterator it=ab.find(5);
if(it!=ab.end()) std::cout<<it-ab.begin()<<std::endl;


There is no operator - defined for it, that's what the compiler is
telling you. If you need to know how far it's from the start (though
I am not sure why you need that), use 'std::distance' function.
else { std::cout<"There is no:"<<j<<" in "<<i<<std::endl;
}
}
return 0;
}

This is the error:
error: no match for 'operator-' in 'it - (+(&ab)->std::vector<_Tp,
_Alloc>::eek:perator[] [with _Tp = std::set<unsigned int,
std::less<unsigned int>, std::allocator<unsigned int> >, _Alloc =
std::allocator<std::set<unsigned int, std::less<unsigned int>,
std::allocator<unsigned int> > >](0u))->std::set<_Key, _Compare,
_Alloc>::begin [with _Key = unsigned int, _Compare =
std::less<unsigned int>, _Alloc = std::allocator<unsigned int>]()'
/usr/lib/gcc/i386-redhat-linux/3.4.2/../../../../include/c++/3.4.2/
bits/stl_bvector.h:180: note: candidates are: ptrdiff_t std::eek:perator-
(const std::_Bit_iterator_base&, const std::_Bit_iterator_base&)

V
 
J

Jonathan Lane

The problem here is that there is no operator- for the iterator.

Take a look at the distance algorithm.
 
R

Renzr

Renzr said:
I have a problem about the std::set<>iterator. After finding a term in
the std::set<>, i want to know the distance from
the current term to the begin(). But i have got a error. Please offer
me help, thank you. I am a freshman about the STL. The following is
the code.
#include <set>
#include <iostream>
#include <vector>
int main()
{
std::set<unsigned int> a;
a.insert(1); a.insert(2); a.insert(3); a.insert(4); a.insert(5);
std::set<unsigned int> b;
b.insert(6); b.insert(7); b.insert(8); b.insert(9); b.insert(10);
std::vector<std::set<unsigned int> > ab(2);
ab[0]= a; ab[1]=b;
{
const unsigned int i=0, j=5;
std::set<unsigned int>::iterator it=ab.find(5);
if(it!=ab.end()) std::cout<<it-ab.begin()<<std::endl;


There is no operator - defined for it, that's what the compiler is
telling you. If you need to know how far it's from the start (though
I am not sure why you need that), use 'std::distance' function.


else { std::cout<"There is no:"<<j<<" in "<<i<<std::endl;
}
}
return 0;
}
This is the error:
error: no match for 'operator-' in 'it - (+(&ab)->std::vector<_Tp,
_Alloc>::eek:perator[] [with _Tp = std::set<unsigned int,
std::less<unsigned int>, std::allocator<unsigned int> >, _Alloc =
std::allocator<std::set<unsigned int, std::less<unsigned int>,
std::allocator<unsigned int> > >](0u))->std::set<_Key, _Compare,
_Alloc>::begin [with _Key = unsigned int, _Compare =
std::less<unsigned int>, _Alloc = std::allocator<unsigned int>]()'
/usr/lib/gcc/i386-redhat-linux/3.4.2/../../../../include/c++/3.4.2/
bits/stl_bvector.h:180: note: candidates are: ptrdiff_t std::eek:perator-
(const std::_Bit_iterator_base&, const std::_Bit_iterator_base&)

V



Thanks for your solution.
The resean is in my FEM code, I want to get the local position of DOF
in the ith row.
So i design the std::vector<std::set<unsigned int> >.
Maybe std::vector<std::vector<unsigned int> > is prefered.
In my loop to ith row (std::vector), several "unsigned int" will be
added into std::vector.
And i need the sorted "unsigned int" in std::vector. So, I have two
ways.
The first is to design the std::vector as std::vector<unsigned
int>. But this way we should involve in std::sort() on
std::vector<unsigned int>. The second way is to design the
std::vector[i] as std::set said:
std::set<>, it is not easy like std::vector<>.
And also, to get the local postion of value T in std::set<unsigned
int> of std::vector is also not easy like std::vector<>.
That is my problem.
So, I have two questions.
1st, Why not std::set<> offer operator , where i is the local
index?
2nd, Why not std::set<>::iterator is invalid in "iterator- begin()"?
 
V

Victor Bazarov

Renzr said:
[..] I have two questions.
1st, Why not std::set<> offer operator , where i is the local
index?


Because 'std::set' is not a sequential container. Only sequences
are required to provide indexing.
2nd, Why not std::set<>::iterator is invalid in "iterator- begin()"?

Because it's not a random-access iterator. It's a bidirectional
iterator that is not required to provide the subtraction operator.

You need to decide on what container to use based on which part of
its functionality you use the most. If it's insertion and iteration,
and rarely getting the "index", 'std::set' would do nicely. If you
insert rarely (or only once), and then you need to index within the
container the rest of its life, you might be better off with the
vector, as you pointed out. Yes, you need it sorted, but that's
not as expensive as you might think. If you know the maximum # of
DOF, you can reserve a certain size in your vectors to prevent
reallocations when inserting.

V
 
G

Guest

Renzr said:
I have a problem about the std::set<>iterator. After finding a term in
the std::set<>, i want to know the distance from
the current term to the begin(). But i have got a error. Please offer
me help, thank you. I am a freshman about the STL. The following is
the code.
#include <set>
#include <iostream>
#include <vector>
int main()
{
std::set<unsigned int> a;
a.insert(1); a.insert(2); a.insert(3); a.insert(4); a.insert(5);
std::set<unsigned int> b;
b.insert(6); b.insert(7); b.insert(8); b.insert(9); b.insert(10);
std::vector<std::set<unsigned int> > ab(2);
ab[0]= a; ab[1]=b;
{
const unsigned int i=0, j=5;
std::set<unsigned int>::iterator it=ab.find(5);
if(it!=ab.end()) std::cout<<it-ab.begin()<<std::endl;


There is no operator - defined for it, that's what the compiler is
telling you. If you need to know how far it's from the start (though
I am not sure why you need that), use 'std::distance' function.


else { std::cout<"There is no:"<<j<<" in "<<i<<std::endl;
}
}
return 0;
}
This is the error:
error: no match for 'operator-' in 'it - (+(&ab)->std::vector<_Tp,
_Alloc>::eek:perator[] [with _Tp = std::set<unsigned int,
std::less<unsigned int>, std::allocator<unsigned int> >, _Alloc =
std::allocator<std::set<unsigned int, std::less<unsigned int>,
std::allocator<unsigned int> > >](0u))->std::set<_Key, _Compare,
_Alloc>::begin [with _Key = unsigned int, _Compare =
std::less<unsigned int>, _Alloc = std::allocator<unsigned int>]()'
/usr/lib/gcc/i386-redhat-linux/3.4.2/../../../../include/c++/3.4.2/
bits/stl_bvector.h:180: note: candidates are: ptrdiff_t std::eek:perator-
(const std::_Bit_iterator_base&, const std::_Bit_iterator_base&)

V



Thanks for your solution.
The resean is in my FEM code, I want to get the local position of DOF
in the ith row.
So i design the std::vector<std::set<unsigned int> >.
Maybe std::vector<std::vector<unsigned int> > is prefered.
In my loop to ith row (std::vector), several "unsigned int" will be
added into std::vector.
And i need the sorted "unsigned int" in std::vector. So, I have two
ways.
The first is to design the std::vector as std::vector<unsigned
int>. But this way we should involve in std::sort() on
std::vector<unsigned int>. The second way is to design the
std::vector as std::set<unsigned int>.


Actually, it is probably cheaper to insert the elements in the vector
and then sort it that it is to insert them into the set. For large
number of elements the difference can be quite noticeable.
 
R

Renzr

Renzr said:
[..] I have two questions.
1st, Why not std::set<> offer operator , where i is the local
index?


Because 'std::set' is not a sequential container. Only sequences
are required to provide indexing.
2nd, Why not std::set<>::iterator is invalid in "iterator- begin()"?

Because it's not a random-access iterator. It's a bidirectional
iterator that is not required to provide the subtraction operator.

You need to decide on what container to use based on which part of
its functionality you use the most. If it's insertion and iteration,
and rarely getting the "index", 'std::set' would do nicely. If you
insert rarely (or only once), and then you need to index within the
container the rest of its life, you might be better off with the
vector, as you pointed out. Yes, you need it sorted, but that's
not as expensive as you might think. If you know the maximum # of
DOF, you can reserve a certain size in your vectors to prevent
reallocations when inserting.

V


Thanks for your solution again. I think I have got you.
In my code, the std::vector<std::set<unsigned int> > is adopted as the
sparse pattenr of the finite-element mesh.
So to the ith row, its relative DOFs are only inserted once, and it
will be used in the assemble frequently.
Yes, I know the maximun # of DOF. And from you, I will chose the
std::vector<>::reserce() to pre-allocate space.
Your solution is perfect.
I will adopte the std::vector<std::vector<unsigned int> >.
And the std::sort(std::vector<>:iterator, std::vector<>::iteraotr) is
not expensive only more.
:) Thanks.
Best regards,
Ren ZhengYong
 
R

Renzr

Renzr wrote:
I have a problem about the std::set<>iterator. After finding a term in
the std::set<>, i want to know the distance from
the current term to the begin(). But i have got a error. Please offer
me help, thank you. I am a freshman about the STL. The following is
the code.
#include <set>
#include <iostream>
#include <vector>
int main()
{
std::set<unsigned int> a;
a.insert(1); a.insert(2); a.insert(3); a.insert(4); a.insert(5);
std::set<unsigned int> b;
b.insert(6); b.insert(7); b.insert(8); b.insert(9); b.insert(10);
std::vector<std::set<unsigned int> > ab(2);
ab[0]= a; ab[1]=b;
{
const unsigned int i=0, j=5;
std::set<unsigned int>::iterator it=ab.find(5);
if(it!=ab.end()) std::cout<<it-ab.begin()<<std::endl;
There is no operator - defined for it, that's what the compiler is
telling you. If you need to know how far it's from the start (though
I am not sure why you need that), use 'std::distance' function.
else { std::cout<"There is no:"<<j<<" in "<<i<<std::endl;
}
}
return 0;
}
This is the error:
error: no match for 'operator-' in 'it - (+(&ab)->std::vector<_Tp,
_Alloc>::eek:perator[] [with _Tp = std::set<unsigned int,
std::less<unsigned int>, std::allocator<unsigned int> >, _Alloc =
std::allocator<std::set<unsigned int, std::less<unsigned int>,
std::allocator<unsigned int> > >](0u))->std::set<_Key, _Compare,
_Alloc>::begin [with _Key = unsigned int, _Compare =
std::less<unsigned int>, _Alloc = std::allocator<unsigned int>]()'
/usr/lib/gcc/i386-redhat-linux/3.4.2/../../../../include/c++/3.4.2/
bits/stl_bvector.h:180: note: candidates are: ptrdiff_t std::eek:perator-
(const std::_Bit_iterator_base&, const std::_Bit_iterator_base&)
V

Thanks for your solution.
The resean is in my FEM code, I want to get the local position of DOF
in the ith row.
So i design the std::vector<std::set<unsigned int> >.
Maybe std::vector<std::vector<unsigned int> > is prefered.
In my loop to ith row (std::vector), several "unsigned int" will be
added into std::vector.
And i need the sorted "unsigned int" in std::vector. So, I have two
ways.
The first is to design the std::vector as std::vector<unsigned
int>. But this way we should involve in std::sort() on
std::vector<unsigned int>. The second way is to design the
std::vector as std::set<unsigned int>.


Actually, it is probably cheaper to insert the elements in the vector
and then sort it that it is to insert them into the set. For large
number of elements the difference can be quite noticeable.


Thanks for your solution.
Your help offer me a right choice on the std::vector<> and std::set<>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,069
Latest member
SimplyleanKetoReviews

Latest Threads

Top