M
Michal Nazarewicz
Let say I have a class template Set which represent set of objects of
given type, and a struct template Pair representing an ordered pair,
ie:
#v+
template<class T>
class Set {
/* ... whatever ... */
public:
bool exists(const T &element) { /* ... */ }
Set<T> &add (const T &element) { /* ... */ return *this; }
Set<T> &remove(const T &element) { /* ... */ return *this; }
void union (const Set<T> &set) { /* ... */ }
};
template<class T>
struct Pair {
T left, right;
};
#v-
Now, I want to create an "alias template" Relation<T> (representing a
binary relation) to mean Set< Pair<T> >. Unfortunately,
`template<class T> typedef Set< Pair<T> > Relation<T>;' won't work, so
I had to define something like:
#v+
template<class T> class Relation : public Set< Pair<T> > { };
#v-
but then add() and remove() methods would return reference to
Set<Pair<T> > which is not the same type as Relation<T> so I'd have to
create class template like:
#v+
template<class T>
class Relation {
Set< Pair<T> > set;
public:
bool exists(const Pair<T> &pair) {
return set.exists(pair);
}
Relation<T> &add (const Pair<T> &pair) {
set.add(pair); return *this;
}
Relation<T> &remove(const Pair<T> &pair) {
set.remove(pair); return *this;
}
void union (const Relation<T> &rel) {
set.union(rel.set);
}
};
#v-
ie. for each method from Set class I'd have to create method in
Relation class. It seems to me like a lot of useless code plus still
Relation<T> and Set< Pair<T> > are two different types so I wouldn't
be able to do:
#v+
Set< Pair<T> > set;
Relation<T> rel;
set.union(rel);
#v-
unless I define an operator const Set< Pair<T> >() and that's just
another piece of useless code.
Is then any nice and easy way to create a nice alias so user wouldn't
have to type Set< Pair<T> > but rather Relation<T>?
given type, and a struct template Pair representing an ordered pair,
ie:
#v+
template<class T>
class Set {
/* ... whatever ... */
public:
bool exists(const T &element) { /* ... */ }
Set<T> &add (const T &element) { /* ... */ return *this; }
Set<T> &remove(const T &element) { /* ... */ return *this; }
void union (const Set<T> &set) { /* ... */ }
};
template<class T>
struct Pair {
T left, right;
};
#v-
Now, I want to create an "alias template" Relation<T> (representing a
binary relation) to mean Set< Pair<T> >. Unfortunately,
`template<class T> typedef Set< Pair<T> > Relation<T>;' won't work, so
I had to define something like:
#v+
template<class T> class Relation : public Set< Pair<T> > { };
#v-
but then add() and remove() methods would return reference to
Set<Pair<T> > which is not the same type as Relation<T> so I'd have to
create class template like:
#v+
template<class T>
class Relation {
Set< Pair<T> > set;
public:
bool exists(const Pair<T> &pair) {
return set.exists(pair);
}
Relation<T> &add (const Pair<T> &pair) {
set.add(pair); return *this;
}
Relation<T> &remove(const Pair<T> &pair) {
set.remove(pair); return *this;
}
void union (const Relation<T> &rel) {
set.union(rel.set);
}
};
#v-
ie. for each method from Set class I'd have to create method in
Relation class. It seems to me like a lot of useless code plus still
Relation<T> and Set< Pair<T> > are two different types so I wouldn't
be able to do:
#v+
Set< Pair<T> > set;
Relation<T> rel;
set.union(rel);
#v-
unless I define an operator const Set< Pair<T> >() and that's just
another piece of useless code.
Is then any nice and easy way to create a nice alias so user wouldn't
have to type Set< Pair<T> > but rather Relation<T>?