We have the following lightweight classes:
struct A {};
struct B { A get_a() const { return /* sth */; } };
And let's suppose I have an ordered container of type A
, and I want to copy objects from another container of type B
to it:
std::copy(b_cont.begin(), b_cont.end(),
std::make_insert_iterator(a_cont, a_cont.end())
);
Of course, it won't work because a_cont
and b_cont
have different types, and classes A
and B
don't provide conversion operators. The most obvious solution is to call the function get_a
for each B
object on the range [b_cont.begin(), b_cont.end())
, so, lets write a custom insert iterator:
template<template<class...> class container>
struct ba_insert_iterator : public std::insert_iterator<container<A> >
{
using std::insert_iterator<container<A>>::insert_iterator;
ba_insert_iterator& operator=(B const& o)
{
std::insert_iterator<container<A>>::operator=(o.get_a());
return *this;
}
};
template<template<class...> class container>
ba_insert_iterator<container> make_a_inserter(container<A>& c)
{ return ba_insert_iterator<container>(c, c.end()); }
Just an iterator that receives an object of type B, instead of another one of type A, and a function to create them easily. But when instantiating the template:
std::copy(b_cont.begin(), b_cont.end(), make_a_inserter(a_cont));
It says that it doesn't find the operator=
because the second operand is an A
object (as expected), but the first operand is an std::insert_iterator<std::set<A> >
!!, so the compiler is "casting" the iterator to its clase base, which of course lacks of a method for receiving B
objects to insert.
Why does it happen?
Aucun commentaire:
Enregistrer un commentaire