473,324 Members | 2,002 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,324 software developers and data experts.

Templates, copy constructor and operator<<

Hello,

I have a problem with using a copy constructor to convert an object of a
templated class to object of another templated class. Let me first
include the code (my question is below):

<code:templates.h>
#include <string>
#include <iostream>

using namespace std;

template<class T> class tempo;

template<class T>
class delo
{
private:
tempo<T> a;
tempo<T> b;
public:
delo () : a(0), b(0) {}
delo ( T c, T d ) : a(c), b(d) {}

void evaluate( tempo<T>& c );
};

template<class T> void printValue( tempo<T> );
template<class T> ostream& operator<< ( ostream&, const tempo<T>& );

template <class T>
class tempo
{
private:
T value;

public:
tempo () : value(0) {}
tempo ( T init ) : value(init) {}
tempo ( delo<T> d ) { d.evaluate(*this); }

friend ostream& operator<< <T>( ostream&, const tempo& );
void compute( tempo& a, tempo& b );
};

template class delo<int>;
template class tempo<int>;
</code:templates.h>

<code:templates.cpp>
#include "templates.h"
#include <iostream>

template <class T>
void delo<T>::evaluate( tempo<T>& c )
{
c.compute( a, b );
}

template <class T>
void tempo<T>::compute( tempo<T>& a, tempo<T>& b )
{
value = a.value + b.value;
}

template <class T>
ostream& operator<< ( ostream& o, const tempo<T>& t )
{
o << "current value = " << t.value << endl;
return o;
}

template ostream& operator<< ( ostream&, const tempo<int>& );
</code:templates.cpp>

The class "delo" is used to delay the computation (compute, in this
example an addition) until it needs to be executed, e.g. when a left-side
object is given or when the result is requested for instance using cout.
In this case, the "delo" object should be converted to a "tempo" object
using the copy constructor, which calls the evaluate function, in which
the compute function is actually called.

So far, so good ... now look at a test program:

<code:test.cpp>
#include "templates.h"
#include <iostream>

using namespace std;

int main ()
{
tempo<int> anInt( 123 );
cout << anInt << endl;

delo<int> aDelInt( 789, 211 );
cout << aDelInt << endl;
}
</code:test.cpp>

The first cout line compiles without any problem, but the second cout line
results in a long error message, which goes like:

<error>
g++ -c test.cpp -o test.o
test.cpp: In function `int main()':
test.cpp:19: no match for `std::ostream& << delo<int>&' operator
/usr/include/c++/3.2.2/bits/ostream.tcc:55: candidates are:
std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
_Traits>::operator<<(std::basic_ostream<_CharT,
_Traits>&(*)(std::basic_ostream<_CharT, _Traits>&)) [with
_CharT = char,
_Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:77:
std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
_Traits>::operator<<(std::basic_ios<_CharT,
_Traits>&(*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT =
char, _Traits
= std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:99:
std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
_Traits>::operator<<(std::ios_base&(*)(std::ios_ba se&)) [with
_CharT = char,
_Traits = std::char_traits<char>]
/usr/include/c++/3.2.2/bits/ostream.tcc:171:
std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT,
_Traits>::operator<<(long int) [with _CharT = char, _Traits =
std::char_traits<char>]
[...]
/usr/include/c++/3.2.2/ostream:211:
std::basic_ostream<_CharT,
_Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&,
char) [with
_CharT = char, _Traits = std::char_traits<char>]
make: *** [test.o] Error 1
</error>

This says it cannot output the "delo" object, while it could copy this
object to a "tempo" object using the copy constructor. But it seems like
it does not know about this copy constructor, or that it cannot use it.
Copying it explicitly (that is, using "cout << tempo<int>( aDelInt )" in
test.cpp does work.

If I use non-templated versions of these classes, it works fine and it
calls the copy constructor like it should.

So my questions are: why does this give an error, and why is it not using
the copy constructor? Are there any limitations? And if so, is there
another way to solve this (without having to do it myself explicitly)?

-- Thanks for any reply.

Franky Backeljauw
University of Antwerp
Department of Mathematics and Computer Science
Jul 19 '05 #1
4 7103

<fr***************@ua.ac.be> wrote in message
news:Pi*************************************@hmacs .ruca.ua.ac.be...
Hello,

I have a problem with using a copy constructor to convert an object of a
templated class to object of another templated class. Let me first
include the code (my question is below):

// Snip a bunch_a_code...

So far, so good ... now look at a test program:

<code:test.cpp>
#include "templates.h"
#include <iostream>

using namespace std;

int main ()
{
tempo<int> anInt( 123 );
cout << anInt << endl;

delo<int> aDelInt( 789, 211 );
// cout << aDelInt << endl;
cout << (tempo <int>) aTemInt << endl;
}
// Snip. a bunch_a_error_message
Copying it explicitly (that is, using "cout << tempo<int>( aDelInt )" in
test.cpp does work.
cout << (tempo <int>) aTemInt << endl;

Yields...

current value = 123

current value = 1000

That what you wanted??

Personally, I wouldn't recommend this or any other cast here...
If I use non-templated versions of these classes, it works fine
and it calls the copy constructor like it should. So my questions are: why does this give an error, and why is it
not using the copy constructor? Are there any limitations?
And if so, is there another way to solve this (without having to
do it myself explicitly)?
That is what I'd do...

const tempo <int> aTemInt (aDelInt);
cout << aTemInt << endl;

-- Thanks for any reply.

HTH
Franky Backeljauw
University of Antwerp
Department of Mathematics and Computer Science


Regards

Brian

Jul 19 '05 #2
On Thu, 3 Jul 2003, Brian MacBride wrote:
cout << (tempo <int>) aTemInt << endl;

Yields...

current value = 123

current value = 1000

That what you wanted??

Personally, I wouldn't recommend this or any other cast here...

That is what I'd do...

const tempo <int> aTemInt (aDelInt);
cout << aTemInt << endl;


Actually, I was wondering why "cout << aDelInt << endl;" does not work. I
have a copy constructor that can copy from "delo" to "tempo", but it does
not get called automatically. This means I cannot output a "delo" object,
although it works when these classes are not templated.

So my guess is that it has something to do with templates again ... doh.

-- Regards,

Franky Backeljauw
University of Antwerp
Department of Mathematics and Computer Science
Jul 19 '05 #3
fr***************@ua.ac.be wrote in message news:<Pi*************************************@hmac s.ruca.ua.ac.be>...
Hello,

I have a problem with using a copy constructor to convert an object of a
templated class to object of another templated class. Let me first
include the code (my question is below): template<class T> class tempo;

template<class T>
class delo
{ /* snip */
public:
delo () : a(0), b(0) {}
delo ( T c, T d ) : a(c), b(d) {}

void evaluate( tempo<T>& c );
}; template <class T>
class tempo
{ /* snip */
public:
tempo () : value(0) {}
tempo ( T init ) : value(init) {}
tempo ( delo<T> d ) { d.evaluate(*this); }
};
/*snip/ The class "delo" is used to delay the computation (compute, in this
example an addition) until it needs to be executed, e.g. when a left-side
object is given or when the result is requested for instance using cout.


This all looks simple and reasonable. However, the compiler can't assume
things are this simple. There might be template specializations of tempo
(e.g. when T==float: tempo<float>) where there is an additional ctor
(e.g. tempo( delo<double> d ) ). Now if the compiler has a delo<double>
it would be ambiguous which tempo<T> to create. Worse, unless the compiler
instantiates delo<T> for all Ts, it doesn't actually know which delo<T>
instances have a delo<double>. And "all Ts" is an infinitely large set.

Therefore the compiler isn't required or even allowed to take implicit
template instantiations into account when doing implicit casts. As
pointed out, if you specify the type T, it will succeed.

Regards,
--
Michiel Salters
Jul 19 '05 #4

<fr***************@ua.ac.be> wrote in message
news:Pi*************************************@hmacs .ruca.ua.ac.be...
On Thu, 3 Jul 2003, Brian MacBride wrote:
cout << (tempo <int>) aTemInt << endl;

Yields...

current value = 123

current value = 1000

That what you wanted??

Personally, I wouldn't recommend this or any other cast here...

That is what I'd do...

const tempo <int> aTemInt (aDelInt);
cout << aTemInt << endl;
Actually, I was wondering why "cout << aDelInt << endl;" does not work. I
have a copy constructor that can copy from "delo" to "tempo", but it does
not get called automatically. This means I cannot output a "delo" object,
although it works when these classes are not templated.


Well, I think it would be a bit of a stretch for the compiler to know
exactly what you intended without some guidance. It could reasonably assume
that you wanted to convert delo <onething> to tempo <whatever> ;-).
So my guess is that it has something to do with templates again ... doh.

-- Regards,

Franky Backeljauw
University of Antwerp
Department of Mathematics and Computer Science


Regards,

Brian

Jul 19 '05 #5

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

Similar topics

3
by: Victor Irzak | last post by:
Hello, I have an ABC. it supports: ostream & operator << I also have a derived class that supports this operator. How can I call operator << of the base class for derived object??? Is it...
3
by: Alicia | last post by:
Hello, I am trying to figure out how to call an overloaded operator<< inherited from a base class. #ifndef PHONECALL #define PHONECALL #include "time.h" #include "interval.h"
3
by: Alex Vinokur | last post by:
Member operators operator>>() and operator<<() in a program below work fine, but look strange. Is it possible to define member operators operator>>() and operator<<() that work fine and look...
0
by: ma740988 | last post by:
Consider #include <iostream> #include <string> #include <map> using namespace std; struct dstream // data_stream class {
3
by: Sensei | last post by:
Hi. I have a problem with a C++ code I can't resolve, or better, I can't see what the problem should be! Here's an excerpt of the incriminated code: === bspalgo.cpp // THAT'S THE BAD...
14
by: lutorm | last post by:
Hi everyone, I'm trying to use istream_iterators to read a file consisting of pairs of numbers. To do this, I wrote the following: #include <fstream> #include <vector> #include <iterator> ...
4
by: bluekite2000 | last post by:
Here A is an instantiation of class Matrix. This means whenever user writes Matrix<float> A=rand<float>(3,2);//create a float matrix of size 3x2 //and fills it up w/ random value cout<<A; the...
3
by: Carlo Capelli | last post by:
I found a change in the following code, that behaved correctly in VC++ 6. #include <strstream> using namespace std; void main() { char x; ostrstream(x, 100) << "pippo" << "pluto" << ends;...
2
by: Harry | last post by:
Hi all, I am writing a logger program which can take any datatype. namespace recordLog { enum Debug_Level {low, midium, high}; class L { std::ofstream os; Debug_Level cdl; const...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...

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.