Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can iter_swap be specialised?

If I have a container std::vector<T*> items, I can create an IndirectIterator which wraps std::vector<T*>::iterator and allows iterating over T's rather than T*'s.

Can I specialise iter_swap for IndirectIterator to make standard algorithms (such as std::sort) swap items by pointer?

i.e., if I write the following, will it have any effect on standard algorithms?

namespace some_namespace
{
    template <typename IterT>
    class IndirectIterator
    {
            IterT m_base;
        public:
            typedef IterT base_iterator;
            typedef /* ... */ reference;

            /* ... */

            reference operator*() const { **m_base; }

            const base_iterator& base() const { return m_base; }
            base_iterator& base() { return m_base; }
    };

    template <typename T>
    void iter_swap(IndirectIterator<T>& a, IndirectIterator<T>& b)
    {
        using std::iter_swap;
        iter_swap(a.base(), b.base());
    }
}

The benefit of this specialisation is that it swaps pointers rather than full T instances, so it's faster (potentially).

like image 916
John Bartholomew Avatar asked Sep 01 '12 11:09

John Bartholomew


3 Answers

As far as I can see, iter_swap is only used in std::reverse, and it does not mention any kind of argument-dependent lookup: it always uses std::iter_swap. And since you are not allowed to overload functions in the std namespace, you're out of luck.

like image 147
R. Martinho Fernandes Avatar answered Nov 17 '22 23:11

R. Martinho Fernandes


Can I specialise iter_swap for IndirectIterator to make standard algorithms (such as std::sort) swap items by pointer?

You can always make your overload/specialization. However your question is whether you can specialize iter_swap inside the namespace std.

I think the answer is unclear from the standard. I have found that in some cases, I had to define a special iter_swap inside std so that std::sort uses it. In gcc std lib std::sort uses the qualified std::iter_swap.

This is probably a defect in std::sort. IMO std::sort should call an unqualified swap_iter.

i.e., if I write the following, will it have any effect on standard algorithms?

Not in GCC (at least) because standard algorithms use qualified std::iter_swap (bug?) I don't think the standard is clear about it.

like image 1
alfC Avatar answered Nov 17 '22 23:11

alfC


You are allowed to reopen std namespace and specialize templates inside std as long as you specialize them for user-defined types. In your case you can actually specialize std::iter_swap for your purposes, just make sure you are doing it in std namespace, not in your own namespace (as in your example). It is not very elegant, but it is allowed.

like image 1
AnT Avatar answered Nov 18 '22 00:11

AnT