Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Can I overload operator<< using a template? (http://www.velocityreviews.com/forums/t459659-can-i-overload-operator-using-a-template.html)

fungus 01-05-2007 01:55 PM

Can I overload operator<< using a template?
 
I have some classes which have a "writeTo()" function
but no operator<<. I want to fix it so that they
all have an operator<< (for consistency).

Can I do something like this:

template <class T>
DataDest& operator<<(DataDest& d, const T& t)
{
t.writeTo(d);
return d;
}

I tried the above but I get errors like "no operator
found which takes a right-hand operand of type XXX".

Do I need to write all the operator<< and operator>>
functions by hand?



Also, a peeve: Why can't the compiler write operator==
and operator< for me automatically? I have some structs
with about 50 members in them (mostly float values) and
to write/maintain operator==/operator< functions for
them is a pain (not to mention bug-prone).

I'm sure the compiler could do this for me automatically
in exactly the same way that it generates operator= and
copy constructors.

Is there a good reason why this wasn't done? Something
I'm missing...?


--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.


Were judging how a candidate will handle a nuclear
crisis by how well his staff creates campaign ads.
Its a completely nonsensical process.

Ondra Holub 01-05-2007 02:17 PM

Re: Can I overload operator<< using a template?
 

fungus napsal:
> I have some classes which have a "writeTo()" function
> but no operator<<. I want to fix it so that they
> all have an operator<< (for consistency).
>
> Can I do something like this:
>
> template <class T>
> DataDest& operator<<(DataDest& d, const T& t)
> {
> t.writeTo(d);
> return d;
> }
>
> I tried the above but I get errors like "no operator
> found which takes a right-hand operand of type XXX".
>
> Do I need to write all the operator<< and operator>>
> functions by hand?
>

It should work with template:

#include <iostream>
#include <string>

class A
{
public:
A(int data1 = 0, int data2 = 0)
: data1_(data1),
data2_(data2)
{
}

void writeTo(std::ostream& os) const
{
os << '[' << data1_ << ';' << data2_ << ']';
}

private:
int data1_;
int data2_;
};

template<typename T, typename S>
S& operator<<(S& d, const T& t)
{
t.writeTo(d);
return d;
}

int main(int argc,char **argv)
{
A a1(3, 5);
A a2(-1, 12);
std::string some_text(" <--> ");

std::cout << a1 << some_text << a2 << '\n';
}

> Also, a peeve: Why can't the compiler write operator==
> and operator< for me automatically? I have some structs
> with about 50 members in them (mostly float values) and
> to write/maintain operator==/operator< functions for
> them is a pain (not to mention bug-prone).
>
> I'm sure the compiler could do this for me automatically
> in exactly the same way that it generates operator= and
> copy constructors.


Well, it could do it, but it does not. it is designed this way, so take
it as it is.


Rolf Magnus 01-05-2007 02:39 PM

Re: Can I overload operator<< using a template?
 
fungus wrote:

> I have some classes which have a "writeTo()" function
> but no operator<<. I want to fix it so that they
> all have an operator<< (for consistency).
>
> Can I do something like this:
>
> template <class T>
> DataDest& operator<<(DataDest& d, const T& t)
> {
> t.writeTo(d);
> return d;
> }
>
> I tried the above but I get errors like "no operator
> found which takes a right-hand operand of type XXX".


That should work. Your code is a bit short, so it's hard to tell why it
wouldn't. It's better to show a minimal, but complete program that exhibits
the observed behavior. The following program does compile without error
here:

class DataDest
{
};

class MyClass
{
public:
void writeTo(DataDest& d) const {}
};

template <class T>
DataDest& operator<<(DataDest& d, const T& t)
{
t.writeTo(d);
return d;
}

int main()
{
MyClass x;
DataDest d;
d << x;
}

> Do I need to write all the operator<< and operator>>
> functions by hand?


The template should be fine.

> Also, a peeve: Why can't the compiler write operator==
> and operator< for me automatically? I have some structs
> with about 50 members in them (mostly float values) and
> to write/maintain operator==/operator< functions for
> them is a pain (not to mention bug-prone).
>
> I'm sure the compiler could do this for me automatically
> in exactly the same way that it generates operator= and
> copy constructors.
>
> Is there a good reason why this wasn't done? Something
> I'm missing...?


I think that's more of a question for comp.std.c++. That newsgroup deals
more with the why than the how. Here, we just accept the C++ language as it
is. ;-)


Noah Roberts 01-05-2007 05:17 PM

Re: Can I overload operator<< using a template?
 

fungus wrote:

> Also, a peeve: Why can't the compiler write operator==
> and operator< for me automatically? I have some structs
> with about 50 members in them (mostly float values) and
> to write/maintain operator==/operator< functions for
> them is a pain (not to mention bug-prone).


Yep, that is a common problem with large, primitive obsessed objects.
You need to rethink your design here and group your data better.

If you want a language that will make your design mistakes easier to
work with you've come to the wrong place. Luckily this one isn't too
hard to fix though if you have a bunch of places where this data is
accessed directly you're going to be there for a while.


mlimber 01-05-2007 05:31 PM

Re: Can I overload operator<< using a template?
 
Noah Roberts wrote:
> fungus wrote:
>
> > Also, a peeve: Why can't the compiler write operator==
> > and operator< for me automatically? I have some structs
> > with about 50 members in them (mostly float values) and
> > to write/maintain operator==/operator< functions for
> > them is a pain (not to mention bug-prone).

>
> Yep, that is a common problem with large, primitive obsessed objects.
> You need to rethink your design here and group your data better.


Besides, what is the compiler supposed to do with pointer members?
Should it compare values or pointed-to-addresses? If values, what
should it do if one or both pointers is null? What if a pointer is
simply uninitialized? (Answer: you've got a very subtle, hard-to-find
bug on your hands because it's hidden in implicit code.)

Cheers! --M


Jacek Dziedzic 01-05-2007 05:55 PM

Re: Can I overload operator<< using a template?
 

> Also, a peeve: Why can't the compiler write operator==
> and operator< for me automatically? I have some structs
> with about 50 members in them (mostly float values) and
> to write/maintain operator==/operator< functions for
> them is a pain (not to mention bug-prone).
>
> I'm sure the compiler could do this for me automatically
> in exactly the same way that it generates operator= and
> copy constructors.
>
> Is there a good reason why this wasn't done? Something
> I'm missing...?


Concerning operator<:

struct foo {
std::string employee_name;
Date date_hired;
// ...
};

foo employers[2]=//...

if(employers[0]>employers[1]) {
// how does the compiler know whether to
// compare by employee_name or by date_hired?
}

HTH,
- J.

Rolf Magnus 01-05-2007 05:59 PM

Re: Can I overload operator<< using a template?
 
mlimber wrote:

> Noah Roberts wrote:
>> fungus wrote:
>>
>> > Also, a peeve: Why can't the compiler write operator==
>> > and operator< for me automatically? I have some structs
>> > with about 50 members in them (mostly float values) and
>> > to write/maintain operator==/operator< functions for
>> > them is a pain (not to mention bug-prone).


I can see that it could be useful to have an auto-generated operator==, but
how would the compiler generate operator<? When is an object 'less' than
another? If all members are 'less'? If one member is 'less'? Which one
then? Or should it do a lexographical comparison? Which order should it use
in that case?

>> Yep, that is a common problem with large, primitive obsessed objects.
>> You need to rethink your design here and group your data better.

>
> Besides, what is the compiler supposed to do with pointer members?
> Should it compare values or pointed-to-addresses?


It should compare the member's value, and since the member is a pointer,
that means the address. The language should never implicitly dereference a
pointer.

> If values, what should it do if one or both pointers is null? What if a
> pointer is simply uninitialized? (Answer: you've got a very subtle,
> hard-to-find bug on your hands because it's hidden in implicit code.)


How does that differ from the assignment operator, which is
compiler-generated by default?


fungus 01-06-2007 10:57 AM

Re: Can I overload operator<< using a template?
 
Rolf Magnus wrote:
> That should work. Your code is a bit short, so it's hard to tell why it
> wouldn't.


I'll have another play with it and see what happens

> It's better to show a minimal, but complete program that exhibits
> the observed behavior.


- but the code is so simple...(!)


> Yep, that is a common problem with large, primitive obsessed objects.
> You need to rethink your design here and group your data better.
>
> If you want a language that will make your design mistakes easier to
> work with you've come to the wrong place.


I have a class which represents a "material".
Materials have a lot of properties, there's no
way around that. I want to put materials in a
std::map for lookup so I need an operator<. I
need to compare two materials so I need an
operator=.

I don't see how there's a "design flaw" here.


--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.


Were judging how a candidate will handle a nuclear
crisis by how well his staff creates campaign ads.
Its a completely nonsensical process.

fungus 01-06-2007 11:00 AM

Re: Can I overload operator<< using a template?
 
mlimber wrote:
> fungus wrote:
>>
>> Why can't the compiler write operator==
>> and operator< for me automatically?

>
> what is the compiler supposed to do with pointer members?
> Should it compare values or pointed-to-addresses? If values, what
> should it do if one or both pointers is null? What if a pointer is
> simply uninitialized?


You have exactly the same problem with assignment
operator and copy constructor but the compiler
seems happy enough to do those for me.

--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.


Were judging how a candidate will handle a nuclear
crisis by how well his staff creates campaign ads.
Its a completely nonsensical process.

fungus 01-06-2007 11:04 AM

Re: Can I overload operator<< using a template?
 
Rolf Magnus wrote:
> fungus wrote:
>> Why can't the compiler write operator==
>> and operator< for me automatically?
>>

> how would the compiler generate operator<?


The code I'm writing at the moment looks like this:


struct item {
float value1;
float value2;
...
};

bool operator<(const item& a, const item& b)
{
// value1
if (a.value1 < b.value1) return true;
if (b.value1 < a.value1) return false;

// value2
if (a.value2 < b.value2) return true;
if (b.value2 < a.value2) return false;

// ...

// If we reach here then a and b are equal
return false;
}


--
<\___/>
/ O O \
\_____/ FTB. For email, remove my socks.


Were judging how a candidate will handle a nuclear
crisis by how well his staff creates campaign ads.
Its a completely nonsensical process.


All times are GMT. The time now is 03:58 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.