C++ Templates: Coding error or compiler bug? - c++

I'm trying to use templates to get std:list of items, where each item has a pointer to the list which contains it, but I keep hitting a compiler message.
Here's a very stripped down version of the code.
template <class E> class Item
{
public:
E* owner; // pointer to list that owns us.
};
template <class E> class BaseList: public std::list<E>
{
protected:
typedef std::list<E> inherited;
public:
void push_back(const E &e)
{
E tmp(e);
tmp.owner = this; // This line gives the error.
inherited::push_back(tmp);
}
};
class MyList;
class MyItem : public Item<MyList>
{
};
class MyList : public BaseList<MyItem>
{
};
void foo() // test code to instantiate template
{
MyList l;
MyItem m;
l.push_back(m);
}
However, my compiler barfs at the line:-
tmp.owner = this;
Error is:
[BCC32 Error] Unit7.cpp(30): E2034 Cannot convert 'BaseList<MyItem> * const' to 'MyList *'
It's like "this" has somehow become const, but I can't see why. Compiler is Codegear C++Builder 2009.
I admit I'm not 100% happy using templates, so I'm unsure if this is my problem or the compilers. The same code without template use compiles fine, but obviously that's not what I want, as I have several item/list classes that want to work this way.
Also, is there a better technique that would avoid having all the "owner" pointers in each item?
EDIT: I think I stripped the example down too far: "MyList" actually introduces new methods, which "MyItem" must then access through the "owner" pointer.
SUMMARY: Thanks for all comments and answers. As the accepted answer says, the problem is simply one of type incompatibility between pointer to a BaseList vs. MyList.
The issues raised about deriving from STL containers and alternative designs are also helpful, but the solution I've used is essentially identical to Luc Touraille's one below.

At line 30, "this" is a pointer to a BaseList<MyIteM>, not a MyList. You can substitute a class with a derived one, but not the other way around.
You can either typedef MyList to be a BaseList<MyItem>, like so:
typedef BaseList<MyItem> MyList
or let MyItem derive from Item<BaseList<MyItem> > instead.
When you derive from a type, you create a different type. When you typedef, you create an alias for that type. So when you typedef the compiler will accept this.

In addition to the answers you already have, I would also point out that the standard library collection classes are not intended to be derived from, as they do not have virtual destructors, and none of their member functions is virtual.

Shouldn't it be tmp.owner = static_cast<MyList*>(this). The type of E is MyList in the MyItem hence E* will be MyList* . The type of this pointer will be BaseList*, hence compiler gives the error that you can not convert the base class pointer to the derived class pointer.

It's hard to say if there's a better solution, when you don't say what it is you need.
Why do each element need a pointer to the list they're stored in?
Anyway, bad things can happen when you inherit from standard containers. They don't have virtual destructors, so you have to be very careful.
A better solution might be to just provide a free function performing the push_back:
template <typename T>
void push_back(std::list<T>& list, const T& t) {
T tmp(t);
tmp.owner = this;
list.push_back(tmp);
}
Apart from avoiding the nonvirtual destructor problem, it also solves your compiler error, because you now only have one type of list.
Of course, if we know why you need this owner pointer in the first place, better still solutions may exist.
Edit
In response to your edit and the comments, use composition, not inheritance:
struct House {
std::string zipcode;
std::list<Person> persons;
void AddPerson(const Person& person) {
Person tmp(person);
tmp.owner = this; // The owner field should be a house, not the list of persons.
persons.push_back(tmp);
}
};
Although I'm not sold on the almost circular references you get when a House stores a list of Persons, and a Person has a pointer to the House it's in.
I'd prefer to decouple these classes as much as possible. If I want to send a letter to a person, I'd call SendLetter(Person, House). Send a letter to this person in that house.

On the side note, you should not extend any classes from std, they are not built for it.
Specifically they don't have virtual destructor so when you call delete on pointer to base class your derived class's destructor will never get called.
You can read more on it Advice on a better way to extend C++ STL container with user-defined methods

I like jalf's free function idea. I'd make it:
template <class X, class Y> // X must have a push_back(Y) member, Y must have an X* owner member
void push_back(X& container, Y value)
{
value.owner = container;
container.push_back(value);
}
This is agnostic over whether the X passed is
a container itself,
is derived from a container as in the original code
or contains a container and has a forwarding push_back function

As it has already been pointed out, the affectation
tmp.owner = this;
fails because this doesn't have the same type as tmp.owner. One solution is to perform a cast, but to do so, you need to provide the container type to BaseList. This can be done using a typedef in Item. Here is the code:
template <class Item> class BaseList
{
public:
void push_back(Item i)
{
i.owner = static_cast<Item::containerType *>(this); // note the cast
items.push_back(i);
}
Item & back() { return items.back(); }
protected:
std::list<Item> items;
};
template <class Container> class Item
{
public:
typedef Container containerType; // Typedef used by BaseList
containerType* owner; // pointer to list that owns us.
};
I also removed the public derivation of std::list: as many said, this is (most of the time) best avoided ; you should consider using composition, or maybe private inheritance.
P.S.: I tried making owner private and BaseList<Item>::push_back friend of Item, but I didn't manage to do it. Is it possible at all? (If too long to answer in comment, feel free to ask a question and answer it)

Regarding const: The type BaseList<MyItem> * const that the compiler mentions is a red herring -- it's not a pointer-to-a-const-object, but a pointer that is const, i.e. an address that won't change. (When you think about it, this never changes to point to something else, does it?)

Related

How to pass a container of derived type to a function needing a container of base type [duplicate]

Consider these classes.
class Base
{
...
};
class Derived : public Base
{
...
};
this function
void BaseFoo( std::vector<Base*>vec )
{
...
}
And finally my vector
std::vector<Derived*>derived;
I want to pass derived to function BaseFoo, but the compiler doesn't let me. How do I solve this, without copying the whole vector to a std::vector<Base*>?
vector<Base*> and vector<Derived*> are unrelated types, so you can't do this. This is explained in the C++ FAQ here.
You need to change your variable from a vector<Derived*> to a vector<Base*> and insert Derived objects into it.
Also, to avoid copying the vector unnecessarily, you should pass it by const-reference, not by value:
void BaseFoo( const std::vector<Base*>& vec )
{
...
}
Finally, to avoid memory leaks, and make your code exception-safe, consider using a container designed to handle heap-allocated objects, e.g:
#include <boost/ptr_container/ptr_vector.hpp>
boost::ptr_vector<Base> vec;
Alternatively, change the vector to hold a smart pointer instead of using raw pointers:
#include <memory>
std::vector< std::shared_ptr<Base*> > vec;
or
#include <boost/shared_ptr.hpp>
std::vector< boost::shared_ptr<Base*> > vec;
In each case, you would need to modify your BaseFoo function accordingly.
Instead of passing the container object (vector<>), pass in begin and end iterators like the rest of the STL algorithms. The function that receives them will be templated, and it won't matter if you pass in Derived* or Base*.
This problem occurs in programming languages that have mutable containers. You cannot pass around a mutable bag of apples as a bag of fruit because you cannot be sure that someone else does not put a lemon into that bag of fruit, after which it no longer qualifies as a bag of apples. If the bag of apples were not mutable, passing it around as a bag of fruit would be fine. Search for covariance/contravariance.
one option is to use a template
template<typename T>
void BaseFoo( const std::vector<T*>& vec)
{
...
}
The drawback is that the implementation has to be in the header and you will get a little code bloat. You will wind up with different functions being instantiated for each type, but the code stays the same. Depending on the use case it's a quick and dirty solution.
Edit, I should note the reason we need a template here is because we are trying to write the same code for unrelated types as noted by several other posters. Templates allow you do solve these exact problems. I also updated it to use a const reference. You should also pass "heavy" objects like a vector by const reference when you don't need a copy, which is basically always.
Generally you would start with a container of base pointers, not the other way.
If you dealing with a third-party library, and this is your only hope, then you can do this:
BaseFoo (*reinterpret_cast<std::vector<Base *> *>(&derived));
Otherwise fix your code with one of the other suggesstions.
Taking Matt Price's answer from above, given that you know in advance what types you want to use with your function, you can declare the function template in the header file, and then add explicit instantiations for those types:
// BaseFoo.h
template<typename T>
void BaseFoo( const std::vector<T*>& vec);
// BaseFoo.cpp
template<typename T>
void BaseFoo( const std::vector<T*>& vec);
{
...
}
// Explicit instantiation means no need for definition in the header file.
template void BaseFoo<Base> ( const std::vector<Base*>& vec );
template void BaseFoo<Derived> ( const std::vector<Derived*>& vec );
If std::vector supported what you're asking for, then it would be possible to defeat the C++ type system without using any casts (edit: ChrisN's link to the C++ FAQ Lite talks about the same issue):
class Base {};
class Derived1 : public Base {};
class Derived2 : public Base {};
void pushStuff(std::vector<Base*>& vec) {
vec.push_back(new Derived2);
vec.push_back(new Base);
}
...
std::vector<Derived1*> vec;
pushStuff(vec); // Not legal
// Now vec contains a Derived2 and a Base!
Since your BaseFoo() function takes the vector by value, it cannot modify the original vector that you passed in, so what I wrote would not be possible. But if it takes a non-const reference and you use reinterpret_cast<std::vector<Base*>&>() to pass your std::vector<Derived*>, you might not get the result that you want, and your program might crash.
Java arrays support covariant subtyping, and this requires Java to do a runtime type check every time you store a value in an array. This too is undesirable.
They are unrelated types -- you can't.

Storing templated objects in a vector (Storing Class<int>, Class<double> in a single vector)

There is a templated class, let it be
template<typename T> class A { std::vector<T> data; };
The problem I am facing here is, users can create several types of this class, but I need to track them, best case is I have a reference of these objects in another vector, but that would not work since all types are different.
Can you recommend a good design pattern which can encapsulate this.
I can store pointers and then typecast it, but its not elegant.
I can change the architecture as well, if the solution provided is good enough.
The basic question I am trying to solve is, I have a class of vector of custom types, how do I store them.
As previous comments stated - you first need to make sure this is what you need.
With that been said, I had a similar requirement in a project of mine, which I eventually solved with inheritance and PIMPL, as follows:
class A{
private:
struct Abstract {
virtual void f() = 0;
};
template <typename T>
struct Implementation : public Abstract {
std::vector<T> data;
virtual void f() {...}
};
std::unique_ptr<Abstract> impl;
public:
template <typename T>
A(): impl(std::make_unique<Implementation<T> >()){}
void f() {impl->f();}
};
This allows you to create a container of objects of type A, and access them via the public interface defined therein (the method f). The underlying type T of each A object is specified on construction. All other implementation details specific to the type T are hidden.
The solution suffers the inherent overhead of virtual functions. I'm not sure how it compares to the std::any approach performance-wise.
std::any is the modern c++17 solution. Specifically, you should use
A<int> a;
a.data.push_back(0);
// fill refernces...
std::vector<std::any> refernces;
refernces.push_back(&a.data[0]);
// check which type is active.
if(int** iPtr = std::any_cast<int*>(&references[0]); iPtr != nullptr)
{
// its an int*
int& i = **iPtr;
// do something with i.
}
These pointers can point into the A<int>::data and A<double>::data vectors.
For a complete reference, see here https://en.cppreference.com/w/cpp/utility/any.

Behavior of Smart Pointer When Casting a shared_ptr<void> to a shared_ptr<type>

I am currently working on a project that requires me to have a vector storing pointers to objects of the same class but with different template values. I want to use shared_ptrs for reasons that I won't get too deep into (mainly that if I want to share a Column between two ColumnLists).
I need to be able to return a casted pointer from a function (as seen below).
So here is a very simplified version:
template <typename ColType>
class Column {
std::vector<ColType>;
};
template <typename ...TypesOfColumns>
class ColumnList {
private:
std::vector< std::shared_ptr<void> > columnsVector;
/* Needs to have a vector storing pointers to multiple Columns
all with different template values */
public:
template <typename ReturnType> std::shared_ptr<ReturnType> GetPointer(int index)
{
return std::static_pointer_cast<ReturnType>(columnsVector.at(index));
};
};
I am wondering if I am getting to some type of undefined behavior here? Will it work as I am hoping: will returning the casted type just add one to the Strong Reference Counter of the void pointer? Can one be deleted before the other one is? Am I risking a memory leak where one gets deleted and the other does not (I doubt this one to be the case)?
As always, thanks for all of the help!!!
static_pointer_cast follows the same rules that static_cast does. It is legal to downcast a pointer-to-base to a pointer-to-derived as long as derived derives from base. As long as you are sure that columnsVector.at(index) contains a shared_ptr<ReturnType> (that is, contains a shared_ptr<void> that originated as a shared_ptr<ReturnType>), what you are doing is legal. If you don't know for sure, you should use dynamic_pointer_cast.
Further, regarding memory, the output of static_pointer_cast shares the same underlying control block as the input, so it's safe that way too. Even if the input were to be deleted first, the output would remain a legal owner of the shared resource, and vice-versa.
IMO much better would be having an abstract column as the base class for the template:
struct AbstractColumn {
virtual ~AbstractColumn() {}
...
};
template<typename Type>
struct Column : AbstractColumn {
std::vector<Type> data;
};
That would provide a place where to put generic methods (e.g. conversion to string, parsing from string etc.) and will also allow you to use pointers to the base class instead of pointers to void.

Casting a container of shared_ptr

I have a method
void foo(list<shared_ptr<Base>>& myList);
Which I'm trying to call with a two different types of lists, one of DerivedClass1 and one of DerivedClass2
list<shared_ptr<DerivedClass1>> myList1;
foo(myList1);
list<shared_ptr<DerivedClass2>> myList2;
foo(myList2);
However this obviously generates a compiler error
error: a reference of type "std::list<boost::shared_ptr<Base>, std::allocator<boost::shared_ptr<Base>>> &" (not const-qualified) cannot be initialized with a value of type "std::list<boost::shared_ptr<DerivedClass1>, std::allocator<boost::shared_ptr<DerivedClass1>>>"
Is there any easy way to cast a container of shared_ptr? Of alternate containers that can accomplish this?
Update: Thanks to everyone who responded. Working within the confines of the language, it seems the best way to go while keeping the method 'as-is' is to use a container of shared_ptr and pass exactly that in (creating a new list at the call site).
I guess I pretty much already knew this, but I remembered reading about other parts of the boost library dealing with containers of shared_ptr and thought maybe it was solved more elegantly by someone else already. From my own further research however these seem to be geared more towards reducing overhead of shared_ptr in cases where a number of pointers are owned exclusively (therefore requiring a single lock per container rather than one per object in the container).
Thanks again, you guys are all awesome!
Change foo so that it follows STL conventions and takes iterators:
template< typename It >
void foo(It begin, It end);
Then pass iterators into your lists
list<shared_ptr<DerivedClass1>> myList1;
foo(myList1.begin(), myList1.end());
list<shared_ptr<DerivedClass2>> myList2;
foo(myList2.begin(), myList2.end());
And everything should work just fine.
Edit:
Note that this isn't anything special to smart pointers. A std::list<T1*>& cannot be initialized with a std::list<T2*>, even if T2 derives from T1.
You can't cast a container of one type to a container of another type. There are a few ways to create a new container from an existing container, if the type of object stored by the existing container is convertible to the type of object stored by the new container:
You can use std::copy to do the conversion element-by-element:
list<shared_ptr<Base> > baseList;
list<shared_ptr<Derived> > derivedList;
std::copy(derivedList.begin(), derivedList.end(), std::back_inserter(baseList));
You can also directly construct baseList using the begin and end iterators from derivedList:
list<shared_ptr<Base> > baseList(derivedList.begin(), derivedList.end());
If your function can take a const reference instead, you can construct a temporary in the function call:
typedef list<shared_ptr<Base> > BaseList;
foo(BaseList(derivedList.begin(), derivedList.end()));
Note that list<shared_ptr<Base>> and list<shared_ptr<DerivedClass1>> (or even shared_ptr<Base> and shared_ptr<DerivedClass1>) are completely different types, even if DerivedClass1 inherits from Base. So casting one to the other would in fact be wrong.
Consider the case when foo attempts to add new elements of type Base to myList. If you could cast myList1 into a list<shared_ptr<Base>> (e.g. with an old-style C cast), and passed it to foo, the result would not be nice.
So the only proper solution I see is to create a new list<shared_ptr<Base>> object and copy the contents of the other list into it, then pass that to foo, as is demonstrated by #James McNellis.
The classical explanation why that wouldn't be a good idea goes as follows:
If you have a list<Apple*> nicely filled with Apples, and you were able to pass it to a function accepting a list<Fruit*>, then there is no stopping the function from putting new Oranges in the list. A list<Fruit*> is simply not substitutable for a list<Apple*> and there exists no relationship.
If you want a function that could work both with a list<Apple*> and list<Orange*>, you could use templates (whether with Iterators, or taking the Container itself, or taking a list<T*> - entirely your choice.
If you really badly wanted to pass a list<Apple*> as if a list<Fruit*>, then I suppose it would be technically possible to come up with proxies for the container / iterators, that use type erasure and what-not to cast the pointers internally / stop invalid casts (putting Oranges into list of Apples), so that you could make the function instead take a list_proxy<Fruit*> which accepts lists of derived types.
Something along the lines of (just a beginning):
#include <list>
#include <boost/shared_ptr.hpp>
template <class T>
class ListWrapperBaseAux
{
public:
virtual ~ListWrapperBaseAux() {}
virtual T* front() = 0;
};
template <class T, class U>
class ListWrapperAux: public ListWrapperBaseAux<T>
{
std::list<U*>* list_ref;
public:
ListWrapperAux(std::list<U*>* list_ref): list_ref(list_ref) {}
virtual T* front() { return dynamic_cast<T*>(list_ref->front()); }
};
template <class T>
class ListProxy
{
boost::shared_ptr<ListWrapperBaseAux<T> > list_ref;
public:
template <class U>
ListProxy(std::list<U*>& li): list_ref(new ListWrapperAux<T, U>(&li)) {}
T* front() { return list_ref->front(); }
};
struct Fruit
{
virtual ~Fruit() {}
};
struct Apple: Fruit {};
struct Orange: Fruit {};
void bake(ListProxy<Fruit> li)
{
Fruit* f = li.front();
}
int main()
{
std::list<Apple*> apples;
bake(apples);
std::list<Orange*> oranges;
bake(oranges);
}

c++ problem with polymorphism and vectors of pointers

Consider the following example code:
class Foo
{
};
class Bar : public Foo
{
};
class FooCollection
{
protected:
vector<shared_ptr<Foo> > d_foos;
};
class BarCollection : public FooCollection
{
public:
vector<shared_ptr<Bar> > &getBars()
{
// return d_foos won't do here...
}
};
I have a problem like this in my current project. The client code uses BarCollection, which stores pointers to Bars in d_foos which is declared in FooCollection. I'd now like to expose the collection of pointers to Bars to the client code. I could just give the client code access to the vector of pointers to Foos and cast these to pointers to Bars in the client code, but this feels wrong since the client doesn't have to know about Foo's existence.
I could also define a get() member that retrieves objects from d_foos and casts them, but this feels quite clumsy. Preferably, I'd like to just return d_foos as a vector<shared_ptr<Bar> > &, but I cannot seem to do this.
It could also be that my design is just plain wrong. It seemed to most natural solution though, as Bar is a specialization of Foo and BarCollection is a specialization of FooCollection and they share functionality.
Could you suggest nice solutions to implement getBars in BarCollection or better design alternatives?
Edit:
Turns out my design was bad indeed. BarCollection is not a FooCollection, despite of requiring all of FooCollection's functionality. My current solution based on the answers below -- which is a lot cleaner -- is now:
class Foo
{
};
class Bar : public Foo
{
};
template<class T>
class Collection
{
vector<shared_ptr<T> > d_items;
};
typedef Collection<Foo> FooCollection;
class BarCollection : public Collection<Bar>
{
// Additional stuff here.
};
Thanks for all the excellent suggestions and examples!
I would suggest exposing iterators from your container classes, instead of the member container. That way it won't matter what the container type is.
The problem is you are trying to mix-and-match two different, pretty-much independent kinds of polymorphism in a way that won't work. The compile-time, type-safe polymorphism of templates won't allow you to substitute a base type for a derived type. C++'s template system makes no association between
class<Foo>
and
class<Bar>
One suggestion might be to create a Foo derived adapter that would cast down to the correct class:
template <class derived, class base>
class DowncastContainerAdapter
{
private:
std::vector< boost::shared_ptr<base> >::iterator curr;
std::vector< boost::shared_ptr<base> >::const_iterator end;
public:
DowncastContainerAdapter(/*setup curr & end iterators*/)
{
// assert derived actually is derived from base
}
boost::shared_ptr<derived> GetNext()
{
// increment iterator
++curr;
return dynamic_cast<base>(*curr);
}
bool IsEnd()
{
return (curr == end);
}
};
Note this class will have the same problem as an iterator, operation on the vector may invalidate this class.
Another thought
You may not realize it, but it may be perfectly fine to just return a vector of Foo. The user of Bar already must have full knowledge of Foo, since by including Bar.h they must get Foo.h through Bar.h. The reason being that for Bar to inherit from Foo, it must have full knowledge of the class via Foo.h. I would suggest rather than using the solution above, if it's possible make Foo (or a super class of Foo) an interface class and pass around vectors of pointers to that interface class. This is a pretty commonly seen pattern and won't raise the eyebrows that this wonky solution I came up with might :). Then again you may have your reasons. Good luck either way.
template<class T>
class MyContainer {
vector<shared_ptr<T> > d_foos;
public:
vector<shared_ptr<T> > & getVector();
};
class FooCollection : public MyContainer<Foo> {
};
class BarCollection : public MyContainer<Bar> {
};
The question is, why would you do that? If you give the user a collection of pointers to Bar, you assume, that there are only Bars in it, so internally storing the pointers in a collection to Foo makes no sense. If you store different subtypes of Foo in your collection of pointer to Foo, you cannot return it as a collection of pointers to Bar, since not all objects in there are Bars.
In the first case, (you know that you have only bars) you should use a templated approach as suggested above.
Otherwise, you have to rethink, what you really want.
Can you not replace this with a Collection templatized on either Foo / Bar?, something like this
class Collection<T> {
protected:
vector<shared_ptr<T> > d_foos;
};
typedef Collection<Foo> FooCollection;
typedef Collection<Bar> BarCollection;
Do you have a special need to have BarCollection derived from FooCollection? Because generally a BarCollection is not a FooCollection, usually a lot of the things that can be done with a FooCollection should not be done with a BarCollection. For example:
BarCollection *bc = new BarCollection();
FooCollection *fc = bc; // They are derived from each other to be able to do this
fc->addFoo(Foo()); // Of course we can add a Foo to a FooCollection
Now we have added a Foo object to what is supposed to be a BarCollection. If the BarCollection tries to access this newly added element and expects it to be a Bar, all kinds of ugly things will happen.
So usually you want to avoid this and don't have your collection classes derived from each other. See also questions about casting containers of derived types for more answers on this topic...
First of all, let's talk about shared_ptr. Do you know about: boost::detail::dynamic_cast_tag ?
shared_ptr<Foo> fooPtr(new Bar());
shared_ptr<Bar> barPtr(fooPtr, boost::detail::dynamic_cast_tag());
This is a very handy way. Under the cover it just performs a dynamic_cast, nothing fancy there but an easier notation. The contract is the same that the classic one: if the object pointed to does not actually is a Bar (or derived from it), then you get a null pointer.
Back to your question: BAD CODE.
BarCollection is NOT a FooCollection, as mentioned you are therefore in trouble because you could introduce other elements in the vector of pointers that Bar ones.
I won't extend on that though, because this is beyond the question at hand, and I think that we (as those trying to answer) should restrain ourselves from that.
You cannot pass a reference, but you can pass a View.
Basically, a View is a new object that act as a Proxy to the old one. It's relatively easy using Boost.Iterators from example.
class VectorView
{
typedef std::vector< std::shared_ptr<Foo> > base_type;
public:
typedef Bar value_type;
// all the cluttering
class iterator: boost::iterator::iterator_adaptor<
iterator,
typename base_type::iterator,
std::shared_ptr<Bar>
>
{
typename iterator_adaptor::reference dereference() const
{
// If you have a heart weakness, you'd better stop here...
return reinterpret_cast< std::shared_ptr<Bar> >(this->base_reference());
}
};
// idem for const_iterator
// On to the method forwarding
iterator begin() { return iterator(m_reference.begin()); }
private:
base_type& m_reference;
}; // class VectorView
The real problem here is of course the reference bit. Getting a NEW shared_ptr object is easy, and allow to perform a dynamic_cast as required. Getting a reference to the ORIGINAL shared_ptr but interpreted as the required type... is really not what I like to see in code.
Note:
There might be a way to do better than that using Boost.Fusion transform_view class, but I could not figure it out.
In particular, using transform_view I can get shared_ptr<Bar> but I can't get a shared_ptr<Bar>& when I dereference my iterator, which is annoying given that the only use of returning a reference to the underlying vector (and not a const_reference) is to actually modify the structure of the vector and the objects it contains.
Note 2:
Please consider refactoring. There have been excellent suggestions there.