set begin() retrieved the minimum element?

P

pmatos

Hi,

If I have set<unsigned int> s; will *(s.begin()) give me the minimum
element of the set? If not, how can I retrieve it?

Cheers,

Paulo Matos
 
S

Steven T. Hatton

pmatos said:
Hi,

If I have set<unsigned int> s; will *(s.begin()) give me the minimum
element of the set?
By default, yes. Set is an associative container which keeps its elements
in sorted order according to the sort criterion. The default sort
criterion uses '<', so it puts the elements in assending order. You can
either use a template parameter to determine an alternative sort criterion
at compile time, or a constructor argument at runtime(though that's a bit
tricky).
 
S

Steven T. Hatton

Rolf said:
Yes, though I'd write s.front() instead.

I don't see that in the standard. According to TC++SL, the only way to
access the elements of a set or multiset is through an iterator. If your
version of C++ suports set::front(), it is (AFAIK) non-standard.
 
P

pmatos

Can't find front() in the standard either. Probably it would be defined
as *(set.begin()), right?

Cheers,

Paulo Matos
 
C

Chris Theis

Rolf Magnus said:
Yes, though I'd write s.front() instead.

AFAIK front is only supplied by vectors, deques and lists. However, assuming
that we have such a container, why would you write front() instead of
begin()? This is just out of curiosity because I tend to use begin() and I
guess that you have a good reason for the suggestion.

Thanks
Chris
 
S

Steven T. Hatton

pmatos said:
Can't find front() in the standard either. Probably it would be defined
as *(set.begin()), right?

That would be the closest thing. Be aware, however, that all access to the
elements of a set or multiset is through pointers to const types. You
cannot modify the elements because that could change the value by which
they are sorted.

BTW, please don't top post in this newsgroup. You may want to take a look at
the C++ FAQ.
http://www.parashift.com/c++-faq-lite/index.html
 
R

Rolf Magnus

Steven said:
I don't see that in the standard. According to TC++SL,

TC++SL?

the only way to access the elements of a set or multiset is through an
iterator. If your version of C++ suports set::front(), it is (AFAIK)
non-standard.

Hmm, I thought front() and back() were functions available in any standard
container. I looked in TC++PL and didn't find it, but I thought that's
because that's because every container has it anyway. Seems I was wrong
about that.
 
A

Andre Kostur

AFAIK front is only supplied by vectors, deques and lists. However,
assuming that we have such a container, why would you write front()
instead of begin()? This is just out of curiosity because I tend to
use begin() and I guess that you have a good reason for the
suggestion.

front() returns a reference to the first element in the container, begin
() returns an iterator to the first element in the container.

So effectively:

T & container::front()
{
return *begin();
}
 
C

Clark S. Cox III

AFAIK front is only supplied by vectors, deques and lists. However,
assuming that we have such a container, why would you write front()
instead of begin()? This is just out of curiosity because I tend to use
begin() and I guess that you have a good reason for the suggestion.

Probably, the biggest reason to use front() is readability:

To many people's eyes:
vec.front() = 5;
is more readable, and expresses the programmer's intent more clearly than:
*vec.begin() = 5;

Or, when passing a vector to a function expecting a pointer to the
first element of an array:
function(&vec.front())
vs.
function(&*vec.begin())
 
C

Carlos Moreno

Rolf said:

Was this a question asking to clarify what TC++SL is? I'm guessing
he meant The C++ Standard Library (??)
Hmm, I thought front() and back() were functions available in any standard
container.

That holds for *sequential* containers. std::set is a slightly
different beast, even though you end up accessing the elements
sequentially.

Carlos
--
 
S

Stephen Howe

Hmm, I thought front() and back() were functions available in any standard
container.

No.
I think the intention is that the names of front() and back() match the
containers that support push_front()/pop_front() and push_back()/pop_back().

Stephen Howe
 
C

Chris Theis

Andre Kostur said:
front() returns a reference to the first element in the container, begin
() returns an iterator to the first element in the container.

So effectively:

T & container::front()
{
return *begin();
}

Looks like I'm already so used to iterators that my head is so clouded that
I didn't think of this ;-)

Cheers
Chris
 
S

Steven T. Hatton

Chris said:
Looks like I'm already so used to iterators that my head is so clouded
that I didn't think of this ;-)

Cheers
Chris

I haven't tested it, but I strongly suspect that will _not_ work, as is. I
believe it needs to be:

const T & container::front() { return *begin(); }

The references to elements of node-based containers such as list, set, map,
multiset, and multimap, are, I believe, a bit more reliable than references
to elements of array based containers such as vector and deque. As a
general rule, holding onto references to elements of a container is
probably a bad practice. I speak from the basis of advise more than
experience.
 
A

Andre Kostur

I haven't tested it, but I strongly suspect that will _not_ work, as
is. I believe it needs to be:

const T & container::front() { return *begin(); }

Depends on the container, of course. list certainly doesn't require the
but the said:
The references to elements of node-based containers such as list, set,
map, multiset, and multimap, are, I believe, a bit more reliable than
references to elements of array based containers such as vector and

I'd prefer to use the phrase 'stable' (persistent?).
deque. As a general rule, holding onto references to elements of a
container is probably a bad practice. I speak from the basis of
advise more than experience.

Bad practice? Not too sure about that. However, one would be encouraged
to research the appropriate iterator and reference lifetimes of the
various containers that you are using...
 
S

Steven T. Hatton

Andre said:
Depends on the container, of course. list certainly doesn't require the
const. set may, and map doesn't. (It may be a pair<const K, V>, but the
pair itself isn't const)

I thought we were talking strictly about sets in the previous discussion.
I'd prefer to use the phrase 'stable' (persistent?).

Actually, after reading chapter 6 of TC++SL, it seems vectors are the only
containers that will present a problem when they are resized. Of course
any reference to an element that is erased, popped, or list::remove()d,
will present a problem. Inserts are a different story than pushes, and
iterators do not behave exactly as do references. Iterators are more
easily invalidated.
Bad practice? Not too sure about that. However, one would be encouraged
to research the appropriate iterator and reference lifetimes of the
various containers that you are using...

I guess it depends on what you know will happen to the container in the
future. I actually have code that keeps a reference to a vector (IIRC - it
may be a boots::array<>, which would be better). Since I don't intend to
change the size of the vector after it's allocated, and the number of
dimensions in 3-space is unlikely to change in the foreseeable future, I'm
probably pretty safe.
 

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
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top