Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

std::iter_swap and proxies

2 views
Skip to first unread message

Mycroft Holmes

unread,
May 25, 2009, 7:00:20 AM5/25/09
to
Hi to all,

we are testing some stl-compliant containers that have iterators on bits (as
vector<bool>) and we noticed some odd behaviour of iter_swap in different
stl implementations.

in visual studio 200x, iter_swap(i,j) performs swap(*i, *j).
but if *i is a proxy and not a real reference, this does not work:

we would have expected something not too intricated, but like this:

template <typename iter_t>
void iter_swap(iter_t a, iter_t b)
{
myswap(*a, *b, static_cast<std::iterator_traits<iter_t>::value_type*>(0) );
}

template <typename T, typenme V>
void myswap(T a, T b, V*)
{
// T is not a reference

V tmp = a;
a = b;
b = tmp;
}

template <typename T, typenme V>
void myswap(T& a, T& b, V*)
{
std::swap(a, b);
}


Obviously we had to specialize std::swap for CONST PROXY_T&, but we have the
vague feeling that this could be avoided. any comments?


Mycroft Holmes

unread,
May 25, 2009, 7:48:48 AM5/25/09
to

> myswap(*a, *b,
> static_cast<std::iterator_traits<iter_t>::value_type*>(0) );

typename...

> template <typename T, typenme V>

typename again... :)

Mycroft Holmes

unread,
May 25, 2009, 8:11:05 AM5/25/09
to
> we would have expected something not too intricated, but like this:

Looking again at the code, I just realized it-s possibly ambiguous. I'll
test it, but I'm pretty sure this should do the trick:


template <typename T, typename V>
struct myswap
{
static void swap(T a, T b)
{


V tmp = a;
a = b;
b = tmp;
}
};


template <typename T, typename V>
struct myswap<T&, V>
{
static void swap(T& a, T& b)
{
std::swap(a, b);
}
};

template <typename iter_t>
void iter_swap(iter_t i, iter_t j)
{
typedef typename std::iterator_traits<iter_t>::value_type val_t;
typedef typename std::iterator_traits<iter_t>::reference ref_t;

myswap<ref_t, val_t>::swap(*i, *j);
}


Igor Tandetnik

unread,
May 25, 2009, 10:36:09 AM5/25/09
to
"Mycroft Holmes" <m.ho...@nospam.it> wrote in message
news:Oc7nAgS3...@TK2MSFTNGP06.phx.gbl

> we are testing some stl-compliant containers that have iterators on
> bits (as vector<bool>)

This is an oxymoron. STL-compliant containers cannot have iterators on
bits. In particular, vector<bool> does not meet container requirements.
For more details, see

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#96
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1999/n1185.pdf
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2160.html

> in visual studio 200x, iter_swap(i,j) performs swap(*i, *j).

See http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#187

> but if *i is a proxy and not a real reference, this does not work

... because i is not a forward iterator. See 24.1.3 table 74, which
requires that *i return a T&, where T is the value_type of the iterator.

> Obviously we had to specialize std::swap for CONST PROXY_T&, but we
> have the vague feeling that this could be avoided. any comments?

If you could specialize swap for your proxies, can't you also specialize
iter_swap for your "iterators"?
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


Mycroft Holmes

unread,
May 25, 2009, 11:25:17 AM5/25/09
to
"Igor Tandetnik" <itand...@mvps.org> wrote in message
news:OC93rYU...@TK2MSFTNGP03.phx.gbl...

> This is an oxymoron. STL-compliant containers cannot have iterators on
> bits. In particular, vector<bool> does not meet container requirements.

> ... because i is not a forward iterator. See 24.1.3 table 74, which
> requires that *i return a T&, where T is the value_type of the iterator.

Thanks for the links; yes, I know the requirements, however I was just
pointing out that it's *possible* for
an stl implementation to work even when requirements are not strictly
satisfied (it can be by mere chance, but gcc stl does work correctly in our
case).


Igor Tandetnik

unread,
May 25, 2009, 12:53:34 PM5/25/09
to
"Mycroft Holmes" <m.ho...@nospam.it> wrote in message
news:u9ajD0U3...@TK2MSFTNGP04.phx.gbl

It may be possible, but it's not required. What better illustration than
discovering that your non-portable code does not, in fact, port?

0 new messages