Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

operator<< with template class doesn't work

0 views
Skip to first unread message

Wolfnoliir

unread,
Aug 30, 2009, 1:12:06 PM8/30/09
to
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.

Victor Bazarov

unread,
Aug 30, 2009, 1:37:02 PM8/30/09
to
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

Francesco

unread,
Aug 30, 2009, 1:39:17 PM8/30/09
to

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-lite/how-to-post.html#faq-5.8

Cheers,
Francesco

Wolfnoliir

unread,
Aug 30, 2009, 1:58:16 PM8/30/09
to
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.

Wolfnoliir

unread,
Aug 30, 2009, 2:02:26 PM8/30/09
to
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-lite/how-to-post.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;
}

Jerry Coffin

unread,
Aug 30, 2009, 2:32:27 PM8/30/09
to
In article <4a9abdb8$0$31038$426a...@news.free.fr>,
wolfn...@gmail.com says...

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.

Wolfnoliir

unread,
Aug 30, 2009, 2:51:23 PM8/30/09
to

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.

Francesco

unread,
Aug 30, 2009, 3:00:32 PM8/30/09
to
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...

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

0 new messages