By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,605 Members | 1,400 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,605 IT Pros & Developers. It's quick & easy.

Extending a class template

P: n/a
Let say I have a class template Pair representing an ordered pair, ie:

#v+
template<class T1, class T2>
class Pair {
T1 a;
T2 b;
public:
Pair() : a(), b() { }
Pair(const Pair<T1, T2&p) : a(p.a), b(p.b) { }
Pair(const T1 &A, const T2 &B) : a(A), b(B) { }

const T1 &left () { return a; }
const T2 &right() { return b; }
};
#v-

Now, if both types are the same I'd like to "add" another method (say)
areEqual() which compares both members (a and b). I could make a
specialization but it would require repeating all common members, ie:

#v+
template<class T>
class Pair<T, T{
T a, b;
public:
Pair() : a(), b() { }
Pair(const Pair<T&p) : a(p.a), b(p.b) { }
Pair(const T &A, const T &B) : a(A), b(B) { }

const T &left () { return a; }
const T &right() { return b; }
bool areEqual() { return a == b; }
};
#v-

Is it possible to some how "extend" a class template with new members
if some condition on template parameters is met?

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
Nov 12 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Michal Nazarewicz wrote:
>
Is it possible to some how "extend" a class template with new members
if some condition on template parameters is met?
The simplest way to add that areEqual function is to make it a free
function:

template <class Ty>
bool areEqual(const Pair<Ty, Ty>&p)
{
return p.left() == p.right();
}

Of course, that approach might not work for other function. In general,
when you need two classes or templates to share capabilities, you
refactor the design: split the original one into two pieces, one derived
from the other, and reuse the base for your new one. For example:

template <class T1, class T2>
class Pair_base
{
private:
T1 a;
T2 b;
public:
Pair_base() : a(), b() {}
Pair_base(const Pair_base& other) : a(other.a), b(other.b) {}
Pair_base(const T1& a0, const T2& b0) : a(a0, b(b0) {}
const T1& left() const { return a; }
const T1& right() const { return b; }
};

template <class T1, class T2>
class Pair : public Pair_base<T1, T2>
{
typedef Pair_base<T1, T2MyBase;
public:
Pair() : MyBase() {}
Pair(const Pair& other) : MyBase(other) {}
Pair_base(const T1& a0, const T2& b0) : MyBase(a0, b0) {}
};

template <class Ty>
class Pair : public Pair_base<Ty, Ty>
{
typedef Pair_base<Ty, TyMyBase;
public:
Pair() : MyBase() {}
Pair(const Pair& other) : MyBase(other) {}
Pair_base(const T1& a0, const T2& b0) : MyBase(a0, b0) {}
bool areEqual() const { return left() == right(); }
};

--

-- Pete
Roundhouse Consulting, Ltd. -- www.versatilecoding.com
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." For more information about this book, see
www.petebecker.com/tr1book.
Nov 12 '06 #2

P: n/a

Michal Nazarewicz wrote:
Let say I have a class template Pair representing an ordered pair, ie:

#v+
template<class T1, class T2>
class Pair {
T1 a;
T2 b;
public:
Pair() : a(), b() { }
Pair(const Pair<T1, T2&p) : a(p.a), b(p.b) { }
Pair(const T1 &A, const T2 &B) : a(A), b(B) { }

const T1 &left () { return a; }
const T2 &right() { return b; }
};
#v-

Now, if both types are the same I'd like to "add" another method (say)
areEqual() which compares both members (a and b). I could make a
specialization but it would require repeating all common members, ie:

#v+
template<class T>
class Pair<T, T{
T a, b;
public:
Pair() : a(), b() { }
Pair(const Pair<T&p) : a(p.a), b(p.b) { }
Pair(const T &A, const T &B) : a(A), b(B) { }

const T &left () { return a; }
const T &right() { return b; }
bool areEqual() { return a == b; }
};
#v-

Is it possible to some how "extend" a class template with new members
if some condition on template parameters is met?
Have u seen the Boost MPL library, in particular the template 'is_same'
I think something like this could work

enable_if_c<is_same<T1,T2>,bool>::type areEqual() { return a == b; }

so that this function only comes into play if T1 and T2 are the same,
even if the line I have written above is incorrect I am sure it is very
close what will work.
Boost has some funcky stuff like that, for example is_base is another
very useful one.

Nov 12 '06 #3

P: n/a
this is one way:

template<class T, bool b>
struct pair_bs {};

template<class T>
struct pair_bs<T, true>
{
bool areEqual()
{
T * pT = static_cast<T*>(this);
return pT->left() == pT->right();
}
};

use type trait (boost for example)

template<class T1, class T2>
class Pair : public pair_bs<Pair<T1, T2>, ::boost::is_same<T1,
T2>::value>
{
T1 a;
T2 b;
public:
Pair() : a(), b() { }
Pair(const Pair<T1, T2&p) : a(p.a), b(p.b) { }
Pair(const T1 &A, const T2 &B) : a(A), b(B) { }

const T1 &left () { return a; }
const T2 &right() { return b; }
};
Nov 13 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.