Boris wrote:
I was making a part of an application more and more generic when I suddenly
ended up with code like this:
template <class T>
struct MenuItems {
T &m;
MenuItems(T &m);
};
template <class T>
struct Menu {
T items;
Menu() : items(*this) { }
};
Are you suggesting that a Menu can only hold one item?
>
template <class T>
MenuItems<T>::MenuItems(T &m) : m(m) { }
If these classes were no templates the code would compile without any
problems. But now with these templates it's impossible to instantiate them
with each other. You end up with something like
Menu<MenuItems<Menu<MenuItems<Menu ... Is there any trick or I went a bit
too far and have to go back to complete types?
I'm still failing to see why an item needs a pointer to its own menu /
container.
If the menu needs to somehow modify the display, thats not the item's
concern.
#include <iostream>
#include <ostream>
#include <list>
#include <iterator>
template < class T >
struct MenuItem
{
MenuItem( T obj ) : t(obj) { }
private:
T t;
/* friend op<< */
friend std::ostream& operator<<(std::ostream& os, const MenuItem< T
>& r_i)
{
return os << r_i.t;
}
};
template< class T >
struct Menu
{
std::list< T menuitems; // or vector, deque, set
};
template< class T >
std::ostream& operator<<(std::ostream& os, const Menu< T >& r_m)
{
std::copy( r_m.menuitems.begin(),
r_m.menuitems.end(),
std::ostream_iterator< T >(os,"\n") );
return os;
}
int main()
{
Menu< MenuItem< std::string menu;
menu.menuitems.push_back(MenuItem< std::string >("string 0"));
menu.menuitems.push_back(MenuItem< std::string >("string 1"));
menu.menuitems.push_back(MenuItem< std::string >("string 2"));
std::cout << menu;
}
/*
string 0
string 1
string 2
*/