Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > operator<< with template class doesn't work

Reply
Thread Tools

operator<< with template class doesn't work

 
 
Wolfnoliir
Guest
Posts: n/a
 
      08-30-2009
Hi,

I am trying to output a template class to 'cout' but my code doesn't
compile; here is gcc's error message:

/tmp/ccnNaceV.o: In function `main':
main.cpp.text+0x6d): undefined reference to
`std::basic_ostream<char, std::char_traits<char> >& operator<<
<char>(std::basic_ostream<char, std::char_traits<char> >&,
Sudoku<char>&)'
collect2: ld returned 1 exit status

and here is the code:

157 template<class T>
158 ostream& operator<<(ostream& os, const Sudoku<T>& s)
159 {
160 for (char i=0; i < s.size; i++)
161 {
162 for (char j=0; j < s.size; j++)
163 {
164 if ( s.is_true(i, j) && HAS_BOLD )
165 {
166 os << "\033[1m" << s.get(i,j) << "\033[0m\t";
167 }
168 else
169 os << s.matrix->at(i,j) << "\t";
170 }
171 os << "\n";
172 }
173 return os;
174 }
175
176 int main()
177 {
178 Sudoku<char> s;
179 //cout << s;
180 operator<<(cout, s);
181 return 0;
182 }

I have declared
friend ostream& operator<<(ostream& os, Sudoku<T2>& s);
in the template class Sudoku.

Thanks.
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      08-30-2009
Wolfnoliir wrote:
> [..] and here is the code:
>
> 157 template<class T>
> 158 ostream& operator<<(ostream& os, const Sudoku<T>& s)
>
> friend ostream& operator<<(ostream& os, Sudoku<T2>& s);


Read the two declarations carefully and see if you can notice any
difference[s].

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
 
Francesco
Guest
Posts: n/a
 
      08-30-2009
On 30 Ago, 19:12, Wolfnoliir <wolfnol...@gmail.com> wrote:
> Hi,
>
> I am trying to output a template class to 'cout' but my code doesn't
> compile; here is gcc's error message:
>
> /tmp/ccnNaceV.o: In function `main':
> main.cpp.text+0x6d): undefined reference to
> `std::basic_ostream<char, std::char_traits<char> >& operator<<
> <char>(std::basic_ostream<char, std::char_traits<char> >&,
> Sudoku<char>&)'
> collect2: ld returned 1 exit status
>
> and here is the code:
>
> 157 template<class T>
> 158 ostream& operator<<(ostream& os, const Sudoku<T>& s)
> 159 {
> 160 for (char i=0; i < s.size; i++)
> 161 {
> 162 for (char j=0; j < s.size; j++)
> 163 {
> 164 if ( s.is_true(i, j) && HAS_BOLD )
> 165 {
> 166 os << "\033[1m" << s.get(i,j) << "\033[0m\t";
> 167 }
> 168 else
> 169 os << s.matrix->at(i,j) << "\t";
> 170 }
> 171 os << "\n";
> 172 }
> 173 return os;
> 174 }
> 175
> 176 int main()
> 177 {
> 178 Sudoku<char> s;
> 179 //cout << s;
> 180 operator<<(cout, s);
> 181 return 0;
> 182 }
>
> I have declared
> friend ostream& operator<<(ostream& os, Sudoku<T2>& s);
> in the template class Sudoku.
>
> Thanks.


Well, to be precise, it compiles. Your problem is that it doesn't
link. Please post sufficient, self contained code that reproduces the
same problem, so that people can copy, paste and test it to help you,
with reference to http://www.parashift.com/c++-faq-lit...t.html#faq-5.8

Cheers,
Francesco
 
Reply With Quote
 
Wolfnoliir
Guest
Posts: n/a
 
      08-30-2009
Victor Bazarov wrote:
> Wolfnoliir wrote:
>> [..] and here is the code:
>>
>> 157 template<class T>
>> 158 ostream& operator<<(ostream& os, const Sudoku<T>& s)
>>
>> friend ostream& operator<<(ostream& os, Sudoku<T2>& s);

>
> Read the two declarations carefully and see if you can notice any
> difference[s].
>
> V


If you are talking about the T2 instead of T; I had to make that
change because to was already declared as the template class of
the Sudoku class so I had to change it.
I am quite shure this is not the origin of the problem.

but thanks.
 
Reply With Quote
 
Wolfnoliir
Guest
Posts: n/a
 
      08-30-2009
Francesco wrote:
> Well, to be precise, it compiles. Your problem is that it doesn't
> link. Please post sufficient, self contained code that reproduces the
> same problem, so that people can copy, paste and test it to help you,
> with reference to http://www.parashift.com/c++-faq-lit...t.html#faq-5.8
>
> Cheers,
> Francesco


compiled with
g++ main.cpp -o main -W -Wall

Here is the entire code:


#include <iostream>
#include <assert.h>
#include <math.h>

#define HAS_BOLD 1

using namespace std;

template<class T> class SimpleMatrix
{
public:
SimpleMatrix(int x, int y) : sizex(x), sizey(y)
{
matrix = new T[x*y];

}
T& at(int x, int y)
{
assert( x < sizex );
assert( y < sizey );
return &matrix[x*sizey + sizex];
}
void set(int x, int y, T s)
{
assert( x < sizex );
assert( y < sizey );
this.at(x, y) = s;
}
void set_all(T s)
{
int size = sizex*sizey;
for (int i=0; i<size; i++)
{
matrix[i] = s;
}
}

private:
T *matrix;
int sizex;
int sizey;
};


template<class T> class Sudoku
{
template<class T2>
friend ostream& operator<<(ostream& os, Sudoku<T2>& s);
public:
Sudoku() : size(9)
{
matrix = new SimpleMatrix<T>(9,9);
truthMatrix = new SimpleMatrix<char>(9,9);

sqrtSize = (T)sqrt(size);
assert( (double)sqrtSize == sqrt(size) );

//T must be a signed type:
assert( (T)(-1) == (int)(-1) );
matrix->set_all(-1);
truthMatrix->set_all(0);
}


T get(T x, T y)
{
return *matrix->at(x,y);
}

char is_true(T x, T y)
{
return *truthMatrix->at(x,y);
}
char set(T x, T y, T s)
{
assert( x < size );
assert( y < size );

if ( !(is_true(x, y)) )
matrix->set(x, y, s);
else
return -1;
return 0;
}
void set_as_true(T x, T y, T s)
{
matrix->set(x, y, s);
truthMatrix->set(x, y, 1);
}

T get_section(T x)
//sections go from 1 to $size
{
return (T)ceil( (double)x / (double)sqrtSize );
}

T* test_coherence(T x, T y)
{
//check lines and columns:
for (T i=0; i < size; i++)
{
if ( matrix->at(i,y) == matrix->at(x,y) && &matrix->at(i,y) !=
&matrix->at(x,y) )
{
return &matrix->at(i,y);
}
else if ( matrix->at(x,i) == matrix->at(x,y) && &matrix->at(x,i) !=
&matrix->at(x,y) )
{
return &matrix->at(x,i);
}
}
//check submatrix:
T sx = get_section(x);
T sy = get_section(y);
T minx = (sx-1)*sqrtSize;
T miny = (sy-1)*sqrtSize;
T maxx = sx*sqrtSize;
T maxy = sy*sqrtSize;
for (T i=minx; i < maxx; i++)
{
for (T j=miny; j < maxy; j++)
{
if (matrix->at(i,j) == matrix->at(x,y) && &matrix->at(x,y) !=
&matrix->at(i,j))
{
return &matrix->at(i,j);
}
}
}
return (T)(-1);
}

private:
SimpleMatrix<T> *matrix;
SimpleMatrix<char> *truthMatrix;
T size;
T sqrtSize;


void set_matrix(T* matrix, T c)
{
for (T i=0; i < size; i++)
{
for (T j=0; j<size; j++)
{
matrix->at(i,j) = c;
}
}
}

};
/*
istream& operator>>(istream& is, Sudoku<T>& s)
{
return NULL;
}
*/

template<class T>
ostream& operator<<(ostream& os, const Sudoku<T>& s)
{
for (char i=0; i < s.size; i++)
{
for (char j=0; j < s.size; j++)
{
if ( s.is_true(i, j) && HAS_BOLD )
{
os << "\033[1m" << s.get(i,j) << "\033[0m\t";
}
else
os << s.matrix->at(i,j) << "\t";
}
os << "\n";
}
return os;
}

int main()
{
Sudoku<char> s;
//cout << s;
operator<<(cout, s);
return 0;
}
 
Reply With Quote
 
Jerry Coffin
Guest
Posts: n/a
 
      08-30-2009
In article <4a9abdb8$0$31038$>,
says...
>
> Victor Bazarov wrote:
> > Wolfnoliir wrote:
> >> [..] and here is the code:
> >>
> >> 157 template<class T>
> >> 158 ostream& operator<<(ostream& os, const Sudoku<T>& s)
> >>
> >> friend ostream& operator<<(ostream& os, Sudoku<T2>& s);

> >
> > Read the two declarations carefully and see if you can notice any
> > difference[s].
> >
> > V

>
> If you are talking about the T2 instead of T; I had to make that
> change because to was already declared as the template class of
> the Sudoku class so I had to change it.
> I am quite shure this is not the origin of the problem.


Look at it again, and see if you don't see another difference -- a
word (a keyword) that's present in one, but not the other...

--
Later,
Jerry.
 
Reply With Quote
 
Wolfnoliir
Guest
Posts: n/a
 
      08-30-2009
Jerry Coffin wrote:
> In article <4a9abdb8$0$31038$>,
> says...
>> Victor Bazarov wrote:
>>> Wolfnoliir wrote:
>>>> [..] and here is the code:
>>>>
>>>> 157 template<class T>
>>>> 158 ostream& operator<<(ostream& os, const Sudoku<T>& s)
>>>>
>>>> friend ostream& operator<<(ostream& os, Sudoku<T2>& s);
>>> Read the two declarations carefully and see if you can notice any
>>> difference[s].
>>>
>>> V

>> If you are talking about the T2 instead of T; I had to make that
>> change because to was already declared as the template class of
>> the Sudoku class so I had to change it.
>> I am quite shure this is not the origin of the problem.

>
> Look at it again, and see if you don't see another difference -- a
> word (a keyword) that's present in one, but not the other...
>


I indeed forgot the 'const'. That was a pretty stupid mistake.
I think I can now solve my problem by adding a few other 'const's
that I forgot.

Thank you.
 
Reply With Quote
 
Francesco
Guest
Posts: n/a
 
      08-30-2009
On 30 Ago, 20:51, Wolfnoliir <wolfnol...@gmail.com> wrote:
> Jerry Coffin wrote:
> > In article <4a9abdb8$0$31038$426a7...@news.free.fr>,
> > wolfnol...@gmail.com says...
> >> Victor Bazarov wrote:
> >>> Wolfnoliir wrote:
> >>>> [..] and here is the code:

>
> >>>> 157 template<class T>
> >>>> 158 ostream& operator<<(ostream& os, const Sudoku<T>& s)

>
> >>>> friend ostream& operator<<(ostream& os, Sudoku<T2>& s);
> >>> Read the two declarations carefully and see if you can notice any
> >>> difference[s].

>
> >>> V
> >> If you are talking about the T2 instead of T; I had to make that
> >> change because to was already declared as the template class of
> >> the Sudoku class so I had to change it.
> >> I am quite shure this is not the origin of the problem.

>
> > Look at it again, and see if you don't see another difference -- a
> > word (a keyword) that's present in one, but not the other...

>
> I indeed forgot the 'const'. That was a pretty stupid mistake.
> I think I can now solve my problem by adding a few other 'const's
> that I forgot.
>
> Thank you.


Fine, now that you have solved that issue, please note that there are
several other points you can fix/improve:
- the C-style casts
- the use of #define
- the possible memory leak due to your use of operator new
- the test for signed types (use the functions found in <limits>
instead)

Refer to the FAQ I linked and you'll find solutions to most of your
issues, along with their rationales.

Keep improving your code,
cheers,
Francesco
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Declaring a template class with two template params a friend in anon-template class A L C++ 1 08-25-2010 07:25 AM
r H2 deduce deduce template argument of a template class inheritingfrom a non template base? nguillot C++ 5 03-08-2009 05:56 PM
How to use the template member function of a template in the memberfunction of another template class? Peng Yu C++ 3 10-26-2008 03:51 PM
template template arguments: expected a class template, got `Component<T1, T2, T3> gary.bernstein@gmail.com C++ 1 06-08-2007 07:10 AM
A parameterized class (i.e. template class / class template) is not a class? christopher diggins C++ 16 05-04-2005 12:26 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57