473,513 Members | 2,454 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Help with operator overloading

I have the following simple program. I just want to be able to do math
operations (+, -, =)on Timer sublcasses, but want to handle cases
where either rhs or lhs is an intrinsic value, However, the compile
fails in my g++ 2.95 compiler during the 2nd to last line of the
main() with

template.cpp: In function `int main()':
template.cpp:24: `operator +<int>(int, const int &)' must have an
argument of class or enumerated type
template.cpp: In method `int & Timer::operator +<int>(const int &)':
template.cpp:97: instantiated from here
template.cpp:42: request for member `_value' in `t', which is of non-
aggregate type `int'
template.cpp:43: static_cast from `Timer *' to `int *'

Seems like the operator+(T& t) function is being called, instead of
the operator+(int) function. Why?
#include <iostream.h>

class Timer {
template<class T>
friend T& operator+(const int value, const T& t);
public:
Timer();
~Timer();

template<class T>
T& operator+(const T& t);
template<class T>
T& operator+(const int value);
template<class T>
T& operator=(const T& t);
template<class T>
T& operator=(const int value);

int _value;
};

template<class T>
T& operator+(const int value, const T& t)
{
static T temp(value);
temp._value=t._value+value;
return temp;
}

Timer::Timer()
{
}

Timer::~Timer()
{
}

template<class T>
T& Timer::operator+(const T& t)
{
// T* This=dynamic_cast<T*>(this);
this->_value+=t._value;
return *(static_cast<T*>(this));
}

template<class T>
T& Timer::operator+(const int value)
{
T* This=dynamic_cast<T*>(this);
This->_value+=value;
return *This;
}

template<class T>
T& Timer::operator=(const T& t)
{
T* This=dynamic_cast<T*>(this);
This->_value=t.value;
return *This;
}

template<class T>
T& Timer::operator=(const int value)
{
T* This=dynamic_cast<T*>(this);
This->_value=value;
return *This;
}

class tRCD : public Timer {
public:
tRCD(const int value);
~tRCD();
};

tRCD::tRCD(const int value)
{
_value=value;
}

tRCD::~tRCD()
{
}

int main()
{
tRCD trcd1(1);
cout << "trcd1._value: " << trcd1._value << endl;
tRCD trcd2(2);
cout << "trcd2._value: " << trcd2._value << endl;
trcd1=trcd1+trcd2;
cout << "trcd1._value: " << trcd1._value << endl;
trcd1=1+trcd1;
cout << "trcd1._value: " << trcd1._value << endl;
trcd1=5;
cout << "trcd1._value: " << trcd1._value << endl;
// trcd1.operator=(trcd1.operator+(1));
trcd1=trcd1+1;
cout << "trcd1._value: " << trcd1._value << endl;
return 0;
}

Mar 21 '07 #1
11 1953
Zilla wrote:
I have the following simple program. I just want to be able to do math
operations (+, -, =)on Timer sublcasses, but want to handle cases
where either rhs or lhs is an intrinsic value, However, the compile
fails in my g++ 2.95 compiler during the 2nd to last line of the
main() with

template.cpp: In function `int main()':
template.cpp:24: `operator +<int>(int, const int &)' must have an
argument of class or enumerated type
template.cpp: In method `int & Timer::operator +<int>(const int &)':
template.cpp:97: instantiated from here
template.cpp:42: request for member `_value' in `t', which is of non-
aggregate type `int'
template.cpp:43: static_cast from `Timer *' to `int *'

Seems like the operator+(T& t) function is being called, instead of
the operator+(int) function. Why?
#include <iostream.h>
There is no such standard header. Try <iostream>.
>
class Timer {
template<class T>
friend T& operator+(const int value, const T& t);
public:
Timer();
~Timer();

template<class T>
T& operator+(const T& t);
Since 'T' is the argument, you can expect that 't' would be
deduced from the argument when you add something to a Timer,
so this one is OK.
template<class T>
T& operator+(const int value);
Here, 'T' is only the return value. WHY? How do you expect
to use this operator? The lhs is 'Timer'. The rhs is 'int'.
Where would T come from?
template<class T>
T& operator=(const T& t);
OK, I can understand that assigning from some type should be
possible. But why do you make the return value 'T&' instead of
'Timer&'?
template<class T>
T& operator=(const int value);
Now, this looks bogus, sorry. Assign to a timer from an 'int'
and return some other value? How do you even get 'T' to factor
into your expression when you write

Timer t;
t = 42; // what's T here?

???
>
int _value;
};

template<class T>
T& operator+(const int value, const T& t)
{
static T temp(value);
temp._value=t._value+value;
return temp;
}

Timer::Timer()
{
}

Timer::~Timer()
{
}

template<class T>
T& Timer::operator+(const T& t)
{
// T* This=dynamic_cast<T*>(this);
this->_value+=t._value;
return *(static_cast<T*>(this));
}

template<class T>
T& Timer::operator+(const int value)
{
T* This=dynamic_cast<T*>(this);
This->_value+=value;
return *This;
}

template<class T>
T& Timer::operator=(const T& t)
{
T* This=dynamic_cast<T*>(this);
This->_value=t.value;
return *This;
}

template<class T>
T& Timer::operator=(const int value)
{
T* This=dynamic_cast<T*>(this);
This->_value=value;
return *This;
}

class tRCD : public Timer {
public:
tRCD(const int value);
~tRCD();
};

tRCD::tRCD(const int value)
{
_value=value;
}

tRCD::~tRCD()
{
}

int main()
{
tRCD trcd1(1);
cout << "trcd1._value: " << trcd1._value << endl;
tRCD trcd2(2);
cout << "trcd2._value: " << trcd2._value << endl;
trcd1=trcd1+trcd2;
cout << "trcd1._value: " << trcd1._value << endl;
trcd1=1+trcd1;
cout << "trcd1._value: " << trcd1._value << endl;
trcd1=5;
cout << "trcd1._value: " << trcd1._value << endl;
// trcd1.operator=(trcd1.operator+(1));
trcd1=trcd1+1;
cout << "trcd1._value: " << trcd1._value << endl;
return 0;
}
Could you explain what exactly it is you're trying to
accomplish?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 21 '07 #2

"Zilla" <zi*****@bellsouth.netwrote in message
news:11*********************@b75g2000hsg.googlegro ups.com...
>I have the following simple program. I just want to be able to do math
operations (+, -, =)on Timer sublcasses, but want to handle cases
where either rhs or lhs is an intrinsic value, However, the compile
fails in my g++ 2.95 compiler during the 2nd to last line of the
main() with

template.cpp: In function `int main()':
template.cpp:24: `operator +<int>(int, const int &)' must have an
argument of class or enumerated type
template.cpp: In method `int & Timer::operator +<int>(const int &)':
template.cpp:97: instantiated from here
template.cpp:42: request for member `_value' in `t', which is of non-
aggregate type `int'
template.cpp:43: static_cast from `Timer *' to `int *'

Seems like the operator+(T& t) function is being called, instead of
the operator+(int) function. Why?
#include <iostream.h>

class Timer {
template<class T>
friend T& operator+(const int value, const T& t);
public:
Timer();
~Timer();

template<class T>
T& operator+(const T& t);
template<class T>
T& operator+(const int value);
template<class T>
T& operator=(const T& t);
template<class T>
T& operator=(const int value);

int _value;
};

template<class T>
T& operator+(const int value, const T& t)
template.cpp:24: `operator +<int>(int, const int &)' must have an
argument of class or enumerated type

Here it winds up being ( int, const int& t)
which is what the error is about. Apparently you can't override int + int
(which makes sense).
{
static T temp(value);
temp._value=t._value+value;
return temp;
}

Timer::Timer()
{
}

Timer::~Timer()
{
}

template<class T>
T& Timer::operator+(const T& t)
{
// T* This=dynamic_cast<T*>(this);
this->_value+=t._value;
template.cpp:42: request for member `_value' in `t', which is of non-
aggregate type `int'

Parm is const int& t.
Then you cast this to an int*.
an int does not have a ._value member
return *(static_cast<T*>(this));
template.cpp:43: static_cast from `Timer *' to `int *'

a Timer* is not an int* and it's bitching.
}

template<class T>
T& Timer::operator+(const int value)
{
T* This=dynamic_cast<T*>(this);
This->_value+=value;
return *This;
}

template<class T>
T& Timer::operator=(const T& t)
{
T* This=dynamic_cast<T*>(this);
This->_value=t.value;
return *This;
}

template<class T>
T& Timer::operator=(const int value)
{
T* This=dynamic_cast<T*>(this);
This->_value=value;
return *This;
}

class tRCD : public Timer {
public:
tRCD(const int value);
~tRCD();
};

tRCD::tRCD(const int value)
{
_value=value;
}

tRCD::~tRCD()
{
}

int main()
{
tRCD trcd1(1);
cout << "trcd1._value: " << trcd1._value << endl;
tRCD trcd2(2);
cout << "trcd2._value: " << trcd2._value << endl;
trcd1=trcd1+trcd2;
cout << "trcd1._value: " << trcd1._value << endl;
trcd1=1+trcd1;
cout << "trcd1._value: " << trcd1._value << endl;
trcd1=5;
cout << "trcd1._value: " << trcd1._value << endl;
// trcd1.operator=(trcd1.operator+(1));
trcd1=trcd1+1;
cout << "trcd1._value: " << trcd1._value << endl;
return 0;
}
Fix the errors.
Mar 21 '07 #3
>
Could you explain what exactly it is you're trying to
accomplish?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -
I want to program regular math expressions (*,/,+,=, etc...) for
objects of type Timers, and its sub-classes. So...

class Timer {
operator-blah(...)
};

class tRCD : public Timer {
blah();
};

class tRP : public Timer {
blah();
};

int main()
{
tRCD trcd1;
tRCD trcd2;
tRP trp;
trcd1=trcd1+1;
trcd1=2*trcd2;
trcd1=trcd1+2+trcd2;
}

IOW, I want the operations in Timer, but need to return the sub-class
type, on the fly...

Mar 22 '07 #4
Zilla wrote:
>Could you explain what exactly it is you're trying to
accomplish?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide
quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

I want to program regular math expressions (*,/,+,=, etc...) for
objects of type Timers, and its sub-classes. So...

class Timer {
operator-blah(...)
};

class tRCD : public Timer {
blah();
};

class tRP : public Timer {
blah();
};

int main()
{
tRCD trcd1;
tRCD trcd2;
tRP trp;
trcd1=trcd1+1;
trcd1=2*trcd2;
trcd1=trcd1+2+trcd2;
}

IOW, I want the operations in Timer, but need to return the sub-class
type, on the fly...
Ah.. I see. So, what book are you currently reading?

....Alright, that wasn't necessarily the right question. But I think
you shouldn't attempt such high flying without getting stable on the
runway yet, so to speak.

Forget the derived classes for now. What do you need to do to make
your class work well in an expression (sometimer + 1) *and* in another
expression like (2 * sometimer)? Good books teach us to make the
operators non-members (otherwise the '2*blah' is not going to work
even if we have the needed converting constructor).

Now, the trouble is that if you have them as non-members, how do we
make them work with derived classes? Your thought was in the right
direction, use templates. But then what, right? Then each of the
function templates should call the class' virtual function to add
an int or multiply with an int. Something like

class Timer {
...
virtual Timer add(int) const;
};

template<class TmTm operator+(Tm const& tm, int i) {
return tm.add(i);
}

template<class TmTm operator+(int i, Tm const& tm) {
return tm+i;
}

class Timer2 : public Timer {
virtual Timer add(int) const; // return value?
};

But now the problem is that 'Timer2::add' function does not return
the right type. It should return 'Timer2', right? What to do
about that?

Here you should probably implement += (which should return the same
object by reference), and you can make the derived class return
the covariant type (itself). But you will have to overload the
operator+= for the derived type as well. You don't sound like you
want to do that.

Another possibility is to let the operators always return 'Timer'
and make sure that the derived classes can assign from it:

class Timer4 : public Timer {
...
Timer4& operator=(Timer const&);
};

In any case, what I see here is a bit incomplete design. It is
not clear what functionality the 'Timer' class should have because
it's unclear what should the operations you presented here to do.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 22 '07 #5
On Mar 22, 1:41 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Zillawrote:
Could you explain what exactly it is you're trying to
accomplish?
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide
quoted text -
- Show quoted text -- Hide quoted text -
- Show quoted text -
I want to program regular math expressions (*,/,+,=, etc...) for
objects of type Timers, and its sub-classes. So...
class Timer {
operator-blah(...)
};
class tRCD : public Timer {
blah();
};
class tRP : public Timer {
blah();
};
int main()
{
tRCD trcd1;
tRCD trcd2;
tRP trp;
trcd1=trcd1+1;
trcd1=2*trcd2;
trcd1=trcd1+2+trcd2;
}
IOW, I want the operations in Timer, but need to return the sub-class
type, on the fly...

Ah.. I see. So, what book are you currently reading?

...Alright, that wasn't necessarily the right question. But I think
you shouldn't attempt such high flying without getting stable on the
runway yet, so to speak.

Forget the derived classes for now. What do you need to do to make
your class work well in an expression (sometimer + 1) *and* in another
expression like (2 * sometimer)? Good books teach us to make the
operators non-members (otherwise the '2*blah' is not going to work
even if we have the needed converting constructor).

Now, the trouble is that if you have them as non-members, how do we
make them work with derived classes? Your thought was in the right
direction, use templates. But then what, right? Then each of the
function templates should call the class' virtual function to add
an int or multiply with an int. Something like

class Timer {
...
virtual Timer add(int) const;
};

template<class TmTm operator+(Tm const& tm, int i) {
return tm.add(i);
}

template<class TmTm operator+(int i, Tm const& tm) {
return tm+i;
}

class Timer2 : public Timer {
virtual Timer add(int) const; // return value?
};

But now the problem is that 'Timer2::add' function does not return
the right type. It should return 'Timer2', right? What to do
about that?

Here you should probably implement += (which should return the same
object by reference), and you can make the derived class return
the covariant type (itself). But you will have to overload the
operator+= for the derived type as well. You don't sound like you
want to do that.

Another possibility is to let the operators always return 'Timer'
and make sure that the derived classes can assign from it:

class Timer4 : public Timer {
...
Timer4& operator=(Timer const&);
};

In any case, what I see here is a bit incomplete design. It is
not clear what functionality the 'Timer' class should have because
it's unclear what should the operations you presented here to do.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide quoted text -

- Show quoted text -
Thanks for your help...

I've been reading the following books and articles - you're correct,
templates are NOT appetizers.
- C++ Primer (Lippman & Lajoie)
- Modern C++ Design (Alexandrescu)
- http://www.hackcraft.net/cpp/templateInheritance
- http://polar.ncep.noaa.gov/mmab/papers/tn185/node7.html
Yes I do NOT want to overload any of the operator-blah functions in my
derived classes, that's the whole point of this excercise. I want to
Timer to implement ALL of them, and the Timer derived classes to
inherit them, but return the correct derived class type. I've used
templates before, but just as containers so I'm not new to the
concept, just new to the concept of temlates AND inheritance. One
thing I'm playing with, is since all my timer "values" will ultimately
of type double, I'm using double as my return type for the functions,
except for operator=(), which still has to return the derived class
type of courxe. IOW,

tRCD trcd;
trcd=trcd+2+trcd;
is...
trcd.operator=(trcd.operator+(operator(2, trcd);
....so if the right-most operator returns a double, the next operator+
() will work, which would also return a double, but the last
operator=() MUST return a tRCD type.

Mar 22 '07 #6
Zilla wrote:
[..] I do NOT want to overload any of the operator-blah functions in my
derived classes, that's the whole point of this excercise. I want to
Timer to implement ALL of them, and the Timer derived classes to
inherit them, but return the correct derived class type. I've used
templates before, but just as containers so I'm not new to the
concept, just new to the concept of temlates AND inheritance. One
thing I'm playing with, is since all my timer "values" will ultimately
of type double, I'm using double as my return type for the functions,
except for operator=(), which still has to return the derived class
type of courxe. IOW,

tRCD trcd;
trcd=trcd+2+trcd;
is...
trcd.operator=(trcd.operator+(operator(2, trcd);
I believe you missed one + and a couple of parens:

trcd.operator=(trcd.operator+(operator+(2, trcd)));

(but I think I get the idea).
...so if the right-most operator returns a double, the next operator+
() will work, which would also return a double, but the last
operator=() MUST return a tRCD type.
OK, let's examine this...

Let's say we use templates to make the return value type correct, OK?

#include <iostream>

template<class D>
class A { // base that implements "everything"
int value;
public:
A(int v) : value(v) {}
D add(int) const;
D add(A const&) const;
};

template<class D>
D operator+(int i, A<Dconst& d) {
return d.add(i);
}

template<class D>
D operator+(A<Dconst& a, int i) {
return a.add(i);
}

template<class D>
D operator+(A<Dconst& a, A<Dconst& aa) {
return a.add(aa);
}

class D1 : public A<D1{ // derived one
public:
// constructors are not inherited, so you need one here
D1(int v) : A<D1>(v) {}
};

class D2 : public A<D2{ // derived two
public:
// constructors are not inherited, so you need one here
D2(int v) : A<D2>(v) {}
};

// Now, the hard part is how to implement the 'add' member in A
template:

template<class D>
D A<D>::add(int i) const
{
D d(this->value + i); // ???
return d;
}

template<class D>
D A<D>::add(A<Dconst& a) const
{
return add(a.value);
}

int main()
{
D1 d1(42), d11(4242);
D2 d2(666), d22(6666);

d11 = d11 + 5;// + d1;
d22 = d22 + 7;// + d2;
return 0;
}

Would that work? Use it as a starting point.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 22 '07 #7
On Mar 22, 4:06 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Zillawrote:
[..] I do NOT want to overload any of the operator-blah functions in my
derived classes, that's the whole point of this excercise. I want to
Timer to implement ALL of them, and the Timer derived classes to
inherit them, but return the correct derived class type. I've used
templates before, but just as containers so I'm not new to the
concept, just new to the concept of temlates AND inheritance. One
thing I'm playing with, is since all my timer "values" will ultimately
of type double, I'm using double as my return type for the functions,
except for operator=(), which still has to return the derived class
type of courxe. IOW,
tRCD trcd;
trcd=trcd+2+trcd;
is...
trcd.operator=(trcd.operator+(operator(2, trcd);

I believe you missed one + and a couple of parens:

trcd.operator=(trcd.operator+(operator+(2, trcd)));

(but I think I get the idea).
...so if the right-most operator returns a double, the next operator+
() will work, which would also return a double, but the last
operator=() MUST return a tRCD type.

OK, let's examine this...

Let's say we use templates to make the return value type correct, OK?

#include <iostream>

template<class D>
class A { // base that implements "everything"
int value;
public:
A(int v) : value(v) {}
D add(int) const;
D add(A const&) const;
};

template<class D>
D operator+(int i, A<Dconst& d) {
return d.add(i);
}

template<class D>
D operator+(A<Dconst& a, int i) {
return a.add(i);
}

template<class D>
D operator+(A<Dconst& a, A<Dconst& aa) {
return a.add(aa);
}

class D1 : public A<D1{ // derived one
public:
// constructors are not inherited, so you need one here
D1(int v) : A<D1>(v) {}
};

class D2 : public A<D2{ // derived two
public:
// constructors are not inherited, so you need one here
D2(int v) : A<D2>(v) {}
};

// Now, the hard part is how to implement the 'add' member in A
template:

template<class D>
D A<D>::add(int i) const
{
D d(this->value + i); // ???
return d;
}

template<class D>
D A<D>::add(A<Dconst& a) const
{
return add(a.value);
}

int main()
{
D1 d1(42), d11(4242);
D2 d2(666), d22(6666);

d11 = d11 + 5;// + d1;
d22 = d22 + 7;// + d2;
return 0;
}

Would that work? Use it as a starting point.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide quoted text -

- Show quoted text -
Thanks, so far it worked for these test cases. It's scary how the
compiler knows how to implement the "=" operation. I'll code it so as
NOT to leave it to chance.

int main()
{
D1 d33(1);
D1 d22(1);
D1 d11=d33;
cout << "d11.value: " << d11.getVal() << endl;
d11=1;
cout << "d11.value: " << d11.getVal() << endl;
d11 = d11 + 1;
cout << "d11.value: " << d11.getVal() << endl;
d11 = 1 + d11;
cout << "d11.value: " << d11.getVal() << endl;
d11 = d22 + d11;
cout << "d11.value: " << d11.getVal() << endl;
return 0;
}

Mar 22 '07 #8
Zilla wrote:
On Mar 22, 4:06 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>[..]

class D1 : public A<D1{ // derived one
public:
// constructors are not inherited, so you need one here
D1(int v) : A<D1>(v) {}
};

class D2 : public A<D2{ // derived two
public:
// constructors are not inherited, so you need one here
D2(int v) : A<D2>(v) {}
};
[..]

Would that work? Use it as a starting point.

V

Thanks, so far it worked for these test cases. It's scary how the
compiler knows how to implement the "=" operation. I'll code it so as
NOT to leave it to chance.

int main()
{
D1 d33(1);
D1 d22(1);
D1 d11=d33;
cout << "d11.value: " << d11.getVal() << endl;
d11=1;
cout << "d11.value: " << d11.getVal() << endl;
d11 = d11 + 1;
cout << "d11.value: " << d11.getVal() << endl;
d11 = 1 + d11;
cout << "d11.value: " << d11.getVal() << endl;
d11 = d22 + d11;
cout << "d11.value: " << d11.getVal() << endl;
return 0;
}
Just to bring it to your attention: it is important to not get the
types mixed up when copy-pasting your code. The class 'D1' is
defined as deriving from 'A<D1>' and 'D2' is from 'A<D2>'. This
is known as CRTP, IIRC. If when you define some 'D3' you make it
derive from 'A<D2>', the stuff can start going wrong and it might
be difficult to find. Or maybe not... Good luck!

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 22 '07 #9
On Mar 22, 5:33 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Zilla wrote:
On Mar 22, 4:06 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
[..]
class D1 : public A<D1{ // derived one
public:
// constructors are not inherited, so you need one here
D1(int v) : A<D1>(v) {}
};
class D2 : public A<D2{ // derived two
public:
// constructors are not inherited, so you need one here
D2(int v) : A<D2>(v) {}
};
[..]
Would that work? Use it as a starting point.
V
Thanks, so far it worked for these test cases. It's scary how the
compiler knows how to implement the "=" operation. I'll code it so as
NOT to leave it to chance.
int main()
{
D1 d33(1);
D1 d22(1);
D1 d11=d33;
cout << "d11.value: " << d11.getVal() << endl;
d11=1;
cout << "d11.value: " << d11.getVal() << endl;
d11 = d11 + 1;
cout << "d11.value: " << d11.getVal() << endl;
d11 = 1 + d11;
cout << "d11.value: " << d11.getVal() << endl;
d11 = d22 + d11;
cout << "d11.value: " << d11.getVal() << endl;
return 0;
}

Just to bring it to your attention: it is important to not get the
types mixed up when copy-pasting your code. The class 'D1' is
defined as deriving from 'A<D1>' and 'D2' is from 'A<D2>'. This
is known as CRTP, IIRC. If when you define some 'D3' you make it
derive from 'A<D2>', the stuff can start going wrong and it might
be difficult to find. Or maybe not... Good luck!

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide quoted text -

- Show quoted text -
Thanks. Yes I noticed this right off. I'm playing with this code now,
and even trying out the straight-forward use of the template, ie,
without the class declarations inheritting the template.

class D1 {
blah()
};

class D2 {
blah()
};

int main()
{
A<D1d1;
A<D2d2;
d1=blah...
}

Mar 23 '07 #10
On Mar 23, 8:37 am, "Zilla" <zill...@bellsouth.netwrote:
On Mar 22, 5:33 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:


Zillawrote:
On Mar 22, 4:06 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>[..]
> class D1 : public A<D1{ // derived one
> public:
> // constructors are not inherited, so you need one here
> D1(int v) : A<D1>(v) {}
> };
> class D2 : public A<D2{ // derived two
> public:
> // constructors are not inherited, so you need one here
> D2(int v) : A<D2>(v) {}
> };
>[..]
>Would that work? Use it as a starting point.
>V
Thanks, so far it worked for these test cases. It's scary how the
compiler knows how to implement the "=" operation. I'll code it so as
NOT to leave it to chance.
int main()
{
D1 d33(1);
D1 d22(1);
D1 d11=d33;
cout << "d11.value: " << d11.getVal() << endl;
d11=1;
cout << "d11.value: " << d11.getVal() << endl;
d11 = d11 + 1;
cout << "d11.value: " << d11.getVal() << endl;
d11 = 1 + d11;
cout << "d11.value: " << d11.getVal() << endl;
d11 = d22 + d11;
cout << "d11.value: " << d11.getVal() << endl;
return 0;
}
Just to bring it to your attention: it is important to not get the
types mixed up when copy-pasting your code. The class 'D1' is
defined as deriving from 'A<D1>' and 'D2' is from 'A<D2>'. This
is known as CRTP, IIRC. If when you define some 'D3' you make it
derive from 'A<D2>', the stuff can start going wrong and it might
be difficult to find. Or maybe not... Good luck!
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide quoted text -
- Show quoted text -

Thanks. Yes I noticed this right off. I'm playing with this code now,
and even trying out the straight-forward use of the template, ie,
without the class declarations inheritting the template.

class D1 {
blah()

};

class D2 {
blah()

};

int main()
{
A<D1d1;
A<D2d2;
d1=blah...

}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -
Ok, I was having problems with your example, so I went back to basics.
I stripped it down to the following code for operator=() only. I can't
even get it to compile...
g++ -c timers.cpp
timers.cpp: In function `int main()':
timers.cpp:35: no match for `tRCD & = double'
timers.cpp:30: candidates are: class tRCD & tRCD::operator =(const
tRCD &)

Why isn't the Timer<T>::operator=(...) being seen?

#include <iostream>

////////////////////////////////////////////////////////
// Base class that defines ALL the operations
template<class T>
class Timer {
public:
Timer();
T& operator=(const double v);

double _min;
};

template<class T>
Timer<T>::Timer() : _min(0)
{
}

template<class T>
T& Timer<T>::operator=(const double v)
{
// do something
}

class tRCD : public Timer<tRCD{
public:
tRCD() : Timer<tRCD>() {}
~tRCD() {}
};

int main()
{
tRCD t1;
t1=3.0;
cout << "t1.min: " << t1._min << endl;
}

Mar 26 '07 #11
Zilla wrote:
On Mar 23, 8:37 am, "Zilla" <zill...@bellsouth.netwrote:
>On Mar 22, 5:33 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:


>>Zillawrote:
On Mar 22, 4:06 pm, "Victor Bazarov" <v.Abaza...@comAcast.net>
wrote:
[..]
>>>> class D1 : public A<D1{ // derived one
public:
// constructors are not inherited, so you need one here
D1(int v) : A<D1>(v) {}
};
>>>> class D2 : public A<D2{ // derived two
public:
// constructors are not inherited, so you need one here
D2(int v) : A<D2>(v) {}
};
[..]
>>>>Would that work? Use it as a starting point.
>>>>V
>>>Thanks, so far it worked for these test cases. It's scary how the
compiler knows how to implement the "=" operation. I'll code it so
as NOT to leave it to chance.
>>>int main()
{
D1 d33(1);
D1 d22(1);
D1 d11=d33;
cout << "d11.value: " << d11.getVal() << endl;
d11=1;
cout << "d11.value: " << d11.getVal() << endl;
d11 = d11 + 1;
cout << "d11.value: " << d11.getVal() << endl;
d11 = 1 + d11;
cout << "d11.value: " << d11.getVal() << endl;
d11 = d22 + d11;
cout << "d11.value: " << d11.getVal() << endl;
return 0;
}
>>Just to bring it to your attention: it is important to not get the
types mixed up when copy-pasting your code. The class 'D1' is
defined as deriving from 'A<D1>' and 'D2' is from 'A<D2>'. This
is known as CRTP, IIRC. If when you define some 'D3' you make it
derive from 'A<D2>', the stuff can start going wrong and it might
be difficult to find. Or maybe not... Good luck!
>>V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide
quoted text -
>>- Show quoted text -

Thanks. Yes I noticed this right off. I'm playing with this code now,
and even trying out the straight-forward use of the template, ie,
without the class declarations inheritting the template.

class D1 {
blah()

};

class D2 {
blah()

};

int main()
{
A<D1d1;
A<D2d2;
d1=blah...

}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -

Ok, I was having problems with your example, so I went back to basics.
I stripped it down to the following code for operator=() only. I can't
even get it to compile...
>g++ -c timers.cpp
timers.cpp: In function `int main()':
timers.cpp:35: no match for `tRCD & = double'
timers.cpp:30: candidates are: class tRCD & tRCD::operator =(const
tRCD &)

Why isn't the Timer<T>::operator=(...) being seen?

#include <iostream>

////////////////////////////////////////////////////////
// Base class that defines ALL the operations
template<class T>
class Timer {
public:
Timer();
T& operator=(const double v);

double _min;
};

template<class T>
Timer<T>::Timer() : _min(0)
{
}

template<class T>
T& Timer<T>::operator=(const double v)
{
// do something
}

class tRCD : public Timer<tRCD{
public:
tRCD() : Timer<tRCD>() {}
~tRCD() {}
};

int main()
{
tRCD t1;
t1=3.0;
cout << "t1.min: " << t1._min << endl;
}
The assignment operator from the base class is hidden by the
assignment operator from the derived class. You need to add
a line with 'using' in it to the 'tRCD' class.

The next thing is to decide what your Timer<T>::operator=
is going to return. I am not sure how you're going to handle
that, since you can't really return *this (the usual value
returned from the assignment op).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 27 '07 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
2566
by: Edward Diener | last post by:
Is there a way to override the default processing of the assignment operator for one's own __value types ? I realize I can program my own Assign method, and provide that for end-users of my class,...
16
3058
by: gorda | last post by:
Hello, I am playing around with operator overloading and inheritence, specifically overloading the + operator in the base class and its derived class. The structure is simple: the base class...
2
2047
by: pmatos | last post by:
Hi all, I'm overloading operator<< for a lot of classes. The question is about style. I define in each class header the prototype of the overloading as a friend. Now, where should I define the...
8
1342
by: John Hardin | last post by:
All: The syntax for overloading the "+" and other simple binary math operators is pretty straightforward, but I can't seem to wrap my brain around the idea that overloading the "+" operator...
67
8577
by: carlos | last post by:
Curious: Why wasnt a primitive exponentiation operator not added to C99? And, are there requests to do so in the next std revision? Justification for doing so: C and C++ are increasingly used...
17
2512
by: Student | last post by:
Hi All, I have an assignment for my Programming language project to create a compiler that takes a C++ file as input and translate it into the C file. Here I have to take care of inheritance and...
3
2273
by: karthik | last post by:
The * operator behaves in 2 different ways. It is used as the value at address operator as well as the multiplication operator. Does this mean * is overloaded in c?
2
2233
by: brzozo2 | last post by:
Hello, this program might look abit long, but it's pretty simple and easy to follow. What it does is read from a file, outputs the contents to screen, and then writes them to a different file. It...
3
3254
by: y-man | last post by:
Hi, I am trying to get an overloaded operator to work inside the class it works on. The situation is something like this: main.cc: #include "object.hh" #include "somefile.hh" object obj,...
8
2951
by: Wayne Shu | last post by:
Hi everyone, I am reading B.S. 's TC++PL (special edition). When I read chapter 11 Operator Overloading, I have two questions. 1. In subsection 11.2.2 paragraph 1, B.S. wrote "In particular,...
0
7259
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7380
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7535
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
5683
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5085
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3232
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1592
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
798
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
455
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.