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

F-bounded polymorphism?

P: n/a
I am writing an application that has two classes that I would like to
treat like vectors (in the mathematical sense); I'd like * and +
operations for scalar multiplication. I also need the std::vector
interface for its dynamic allocation. So, I inherit from std::vector,
and I want to write a function

template<typename S, typename T>
T operator*(const S & op1, const T & op2) {
T ans(op2);
for(typename T::iterator i = ans.begin(); i != ans.end(); ++i) {
i = op1 * *i;
}
return ans;
}

My problem is that this grabs calls for T=<some enum type>. I've
thought of two ways I could prevent this disaster, none of which are
legal C++.

1. I want some sort of bounded polymorphism where T must be a subtype
of vector<S>.
2. I want some sort of "thistype" identifier, so that I can write the
above definition, with "T" replaced by "thistype", and the definition
placed in some "myvec<T>" class that my classes inherit from. in
inherited classes, "thistype" is read at "typeof(*this)".

I suppose I could also rewrite the definition for each class, or use a
macro, but isn't avoiding those the motivation for templates?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Hi

"Gina Yarmel" <ta**********@yahoo.com> wrote in message
news:e4**************************@posting.google.c om...
I am writing an application that has two classes that I would like to
treat like vectors (in the mathematical sense); I'd like * and +
operations for scalar multiplication. I also need the std::vector
interface for its dynamic allocation. So, I inherit from std::vector,
and I want to write a function

template<typename S, typename T>
T operator*(const S & op1, const T & op2) {
T ans(op2);
for(typename T::iterator i = ans.begin(); i != ans.end(); ++i) {
i = op1 * *i;
}
return ans;
}

My problem is that this grabs calls for T=<some enum type>. I've
thought of two ways I could prevent this disaster, none of which are
legal C++.

1. I want some sort of bounded polymorphism where T must be a subtype
of vector<S>.
Such a thing is not available in the standard. You might try the boost
Concept Check library. However, what's wrong with

template<typename S>
vector<S> operator *(const S& sca, const vector<S>& vec) { ... }?
2. I want some sort of "thistype" identifier, so that I can write the
above definition, with "T" replaced by "thistype", and the definition
placed in some "myvec<T>" class that my classes inherit from. in
inherited classes, "thistype" is read at "typeof(*this)".


Which *this are you talking about? Derived classes know about their type;
base classes cannot (for obvious reasons) know about their derived types.
That is, unless the base class is templatized on the derived class, but
that's another story :-). I'm not sure what you want here.

Regards
David Turner

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #2

P: n/a
> template<typename S, typename T>
T operator*(const S & op1, const T & op2) {
T ans(op2);
for(typename T::iterator i = ans.begin(); i != ans.end(); ++i) {
i = op1 * *i;
}
return ans;
}

My problem is that this grabs calls for T=<some enum type>. I've
thought of two ways I could prevent this disaster, none of which are
legal C++.

1. I want some sort of bounded polymorphism where T must be a subtype
of vector<S>.


Why not just
template <typename S> T operator* (const S& op1, const vector <S>& op)
?

Or you can use the "curiously recursive" inheritance pattern like I
did for my library "macstl" (ref my site URL).

template <typename T> class base;
template <typename S> T operator* (const S& op1, const base <T>& op);

and say you have types A, B, C you want to participate in this:

class A: public base <A> { ... };
template <typename X> class B: public base <B <X> > { ... };
template <typename X, typename Y> class C: public base <C <X, Y> > {
.... };

Thus, base acts like a marker interface to limit the operator* to
affect only things that inherit from base. The reason you may need
base <T> instead of just a plain class base is that you may need to
expose or use the T in the base code. It is "compile-time
polymorphism".

Or you can always use std::valarray or the Blitz classes which
basically declare operators on arrays and/or vectors.

Cheers,
Glen Low, Pixelglow Software
www.pixelglow.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #3

P: n/a
ta**********@yahoo.com (Gina Yarmel) wrote in message
news:<e4**************************@posting.google. com>...
I am writing an application that has two classes that I would like to
treat like vectors (in the mathematical sense); I'd like * and +
operations for scalar multiplication. I also need the std::vector
interface for its dynamic allocation. So, I inherit from std::vector,
and I want to write a function

template<typename S, typename T>
T operator*(const S & op1, const T & op2) {
T ans(op2);
for(typename T::iterator i = ans.begin(); i != ans.end(); ++i) {
i = op1 * *i;
}
return ans;
}

My problem is that this grabs calls for T=<some enum type>. I've
thought of two ways I could prevent this disaster, none of which are
legal C++.

1. I want some sort of bounded polymorphism where T must be a subtype
of vector<S>.
2. I want some sort of "thistype" identifier, so that I can write the
above definition, with "T" replaced by "thistype", and the definition
placed in some "myvec<T>" class that my classes inherit from. in
inherited classes, "thistype" is read at "typeof(*this)".

I suppose I could also rewrite the definition for each class, or use a
macro, but isn't avoiding those the motivation for templates?


I don't apprehend your intention but in any case writing such a
template is a bad idea:
1. It catches all multiplication with user types
2. It's implementation isn't generic enough to handle all the
multiplication
(in fact it's not capable of T*S vs S*T)

Though there are ways to check inherritance relations at compile-time
(see SUPERSUBCLASS at moderncppdesign.com, Loki library)
as far as I understand you really want to multiply a scalar value
with 2 kinds of vectors of scalar values. Is it ? Let's try

template<class S> class Vec1 {...} // first vector
template<class S> class Vec2 {...} // second vector

// your implementation renamed
template<typename S, typename T>
T mul_scal_vec(const S & op1, const T & op2) {
T ans(op2);
for(typename T::iterator i = ans.begin(); i != ans.end(); ++i) {
i = op1 * *i;
}
return ans;
}

// operators
template<class S>
Vec1 operator*(const S& scalar,const Vec1& vector)
{ return mul_scal_vec(scalar,vector); }

template<class S>
Vec2 operator*(const S& scalar,const Vec2& vector)
{ return mul_scal_vec(scalar,vector); }

These operators still catch enum but does it still bother you ?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #4

P: n/a
ta**********@yahoo.com (Gina Yarmel) wrote in message news:<e4**************************@posting.google. com>...
I am writing an application that has two classes that I would like to
treat like vectors (in the mathematical sense); I'd like * and +
operations for scalar multiplication. I also need the std::vector
interface for its dynamic allocation. So, I inherit from std::vector,
and I want to write a function

template<typename S, typename T>
T operator*(const S & op1, const T & op2) {
T ans(op2);
for(typename T::iterator i = ans.begin(); i != ans.end(); ++i) {
i = op1 * *i;
}
return ans;
}

My problem is that this grabs calls for T=<some enum type>. I've
thought of two ways I could prevent this disaster, none of which are
legal C++.


you can use restricted templates:

template <bool> struct restricted;
template <> struct restricted<true> { typedef void type; };

template <typename T> void func(
const T& arg,
typename restricted< boost::is_fundamental< T >::value >::type* =0
);

func(3); //ok
func(std::string("not_ok"));

the templated function "func" will be discarded from the overload set
if the test "boost::is_fundamental<T>::value" is false.

joshua lehrer
factset research systems
NYSE:FDS

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #5

P: n/a
"David Turner" <da***@firepro.co.za> wrote
However, what's wrong with

template<typename S>
vector<S> operator *(const S& sca, const vector<S>& vec) { ... }?
It returns a vector, whereas I need a subclass. Consider two classes,
vectors with color, and vectors with smell. When I multiply either, I
should keep their additional characteristics.
Which *this are you talking about? Derived classes know about their type;
base classes cannot (for obvious reasons) know about their derived types.
That is, unless the base class is templatized on the derived class, but that's another story :-). I'm not sure what you want here.


I would want a keyword thistype such that

#include <iostream>

class base {
public:
void some_func() const {
std::cout << typeid(thistype).name();
}
};

class derived : public base {};

int main() {
base foo;
foo.some_func();
}

prints "derived". If this were the case, then I could write

template<typename T>
class myvec : public std::vector<T> {
public:
thistype multiply(T a, thistype b) {/**/}
};

class color_vec : public myvec<int> {};
class smelly_vec : public myvec<int> {};

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #6

P: n/a
> you can use restricted templates:

You can also do the same sort of thing with return types in gcc 3.3
(earlier versions have limited support). The technique is based on
SFINAE and here's good treatise on it:

http://m17n.org/martin/writings/temp...nstraints.html

Cheers,
Glen Low, Pixelglow Software
www.pixelglow.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #7

P: n/a
ta**********@yahoo.com (Gina Yarmel) writes:
"David Turner" <da***@firepro.co.za> wrote
> However, what's wrong with
>
> template<typename S>
> vector<S> operator *(const S& sca, const vector<S>& vec) { ... }?
It returns a vector, whereas I need a subclass. Consider two classes,
vectors with color, and vectors with smell. When I multiply either, I
should keep their additional characteristics.
> Which *this are you talking about? Derived classes know about their type;
> base classes cannot (for obvious reasons) know about their derived types.
> That is, unless the base class is templatized on the derived class, but

> that's another story :-). I'm not sure what you want here.


I would want a keyword thistype such that

#include <iostream>

class base {
public:
void some_func() const {
std::cout << typeid(thistype).name();

Why is typeid(*this).name() insufficient?
}
};

class derived : public base {};

int main() {
base foo;
foo.some_func();
}

prints "derived". If this were the case, then I could write


But that's nonsense. foo is of type base, not derived.

If you make foo of type derived, typeid(*this).name() will do more or
less what you want, modulo the customary variations in the output
of typeid().name() .

[snip]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.