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).
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.
Can I specialise
iter_swap
forIndirectIterator
to make standard algorithms (such asstd::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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With