templates instead of macros

P

Piotr Sawuk

What is the proper c++-way of saying:

template <class Container_>
struct forwards_iterator_toggle
{
typedef Container_ Container;
typedef typename Container::iterator iterator;
typedef typename Container::reverse_iterator reverse_iterator;
typedef backwards_iterator_toggle<Container_> Other;

template<class rIter_>
static typename Other::rIter_ toggle(const rIter_ i)
{return --(i.base());}
};
template <class Container_>
struct backwards_iterator_toggle
{
typedef Container_ Container;
typedef typename Container::reverse_iterator iterator;
typedef typename Container::iterator reverse_iterator;
typedef forwards_iterator_toggle<Container_> Other;

template <typename rIter_>
static typename Other::rIter_ toggle(const rIter_ i)
{return --(typename Other::rIter_)(i);}
};

#include<list>
int main(...)
{
typedef std::list<int> myList;
typedef backwards_iterator_toggle<myList> myToggle;
myList list;
typename myToggle::iterator i=
myToggle::toggle(list.begin());
}
 
B

Ben Pope

Piotr said:
What is the proper c++-way of saying:

I don't really know what it is you are trying to say. I may have got
lost in the excess of typedefs that obviously won't work.

Perhaps a short explanation of what you are trying to achieve would be
useful.

Ben Pope
 
D

Daniel T.

What is the proper c++-way of saying:

template <class Container_>
struct forwards_iterator_toggle
{
typedef Container_ Container;
typedef typename Container::iterator iterator;
typedef typename Container::reverse_iterator reverse_iterator;
typedef backwards_iterator_toggle<Container_> Other;

template<class rIter_>
static typename Other::rIter_ toggle(const rIter_ i)
{return --(i.base());}
};
template <class Container_>
struct backwards_iterator_toggle
{
typedef Container_ Container;
typedef typename Container::reverse_iterator iterator;
typedef typename Container::iterator reverse_iterator;
typedef forwards_iterator_toggle<Container_> Other;

template <typename rIter_>
static typename Other::rIter_ toggle(const rIter_ i)
{return --(typename Other::rIter_)(i);}
};

#include<list>
int main(...)
{
typedef std::list<int> myList;
typedef backwards_iterator_toggle<myList> myToggle;
myList list;
typename myToggle::iterator i=
myToggle::toggle(list.begin());
}

Are you still trying to make an iterator that can change direction at
will? Here you go (it even uses the State pattern rather than
conditionals):

template < typename BiIt >
class reversable_iterator
{
struct direction {
virtual void increment( BiIt& it ) = 0;
virtual void decrement( BiIt& it ) = 0;
};

struct foward : direction {
virtual void increment( BiIt& it ) { ++it; }
virtual void decrement( BiIt& it ) { --it; }
} fwrd;

struct backward : direction {
virtual void increment( BiIt& it ) { --it; }
virtual void decrement( BiIt& it ) { ++it; }
}bckwrd;

direction* which_dir;
BiIt rep;

public:
reversable_iterator( BiIt it ): which_dir( &fwrd ), rep( it ) {
}

typename BiIt::value_type& operator*() { return *rep; }

reversable_iterator& operator++() {
which_dir->increment( rep );
return *this;
}

reversable_iterator& operator--() {
which_dir->decrement( rep );
return *this;
}

void reverse() {
which_dir = ( which_dir == &fwrd ) ?
static_cast<direction*>( &bckwrd ) :
static_cast<direction*>( &fwrd );
}
};
 
P

Piotr Sawuk

Thanks for the 2 answrs to my question, but none was helpful.
I'll try again with a working program:

What is the proper c++-way of saying:

#define FTOGGLEDEF__(name) static typename Other::name \
toggle(const name i) {return --(i.base());}
#define BTOGGLEDEF__(name) static typename Other::name \
toggle(const name i) {return --(typename Other::name)(i);}

template <class Container_>
struct backwards_iterator_toggle;

template <class Container_>
struct forwards_iterator_toggle
{
typedef Container_ Container;
typedef typename Container::iterator iterator;
typedef typename Container::reverse_iterator reverse_iterator;
typedef backwards_iterator_toggle<Container_> Other;

//template<class rIter_> static typename Other::rIter_ toggle(const rIter_ i)
//doesn't work, so I have to use macros, one line for each reverse_iterator:
FTOGGLEDEF__(reverse_iterator)
};

template <class Container_>
struct backwards_iterator_toggle
{
typedef Container_ Container;
typedef typename Container::reverse_iterator iterator;
typedef typename Container::iterator reverse_iterator;
typedef forwards_iterator_toggle<Container_> Other;

BTOGGLEDEF__(reverse_iterator)
};

#include<list>
int main(...)
{
typedef std::list<int> myList;
typedef backwards_iterator_toggle<myList> myToggle;
myList list;
myToggle::iterator i=
myToggle::toggle(list.begin());
}


Of course you'd have to imagine above code with more than one
template-parameter, maybe even containing several structs of
Containers, with one typedef for each iterator into each Container,
and for each reverse-iterator among them there would be the
definition (through macros) of the overloaded 'toggle'-function...

Also you'd have to imagine multiple structs in the manner like
above, each taking the other structs as template-parameters and
each containing multiple functions in the manner of above 'toggle'.
Then you'd get for every such struct n macros cluttering the global
namespace (where n is the amount of 'toggle'-alike functions)...

Again my question: how to evade the use of macros here without
putting the burden of 'dispatching types' onto run-time?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top