Error while testing the "non-template friend function of a templateclass"

  • Thread starter Pierre Barbier de Reuille
  • Start date
P

Pierre Barbier de Reuille

Hi,

after reading the article " The Standard Librarian : Defining Iterators
and Const Iterators" from Matt Austern:
http://www.ddj.com/showArticle.jhtml;jsessionid=41JODBZDWEMBYQSNDLOSKH0CJUNN2JVN?articleID=184401331

I wanted to test using the non-template function friends of template
classes. So I devised this code:

===8<======8<======8<======8<======8<======8<======8<===

#include <iostream>

using namespace std;

template <class T>
struct S
{

friend S foo( const S& s1, const S& s2 )
{
return S( s1.s + s2.s );
}

friend T operator+( const T& a, const S& s )
{
return a+s.s;
}

friend ostream& operator<<( ostream& s, const S& o )
{
s << "S(" << o.s << ")";
return s;
}

S( T a ) : s( a ) {}

T s;
};

int main()
{
S<int> s1( 1 );
S<S<int> > s2( 10 );
cout << foo( s1, s2 );
cout << endl;
return 0;
}

===8<======8<======8<======8<======8<======8<======8<===

It does compile but segfaults at runtime o_O
Could someone explain to me what I did wrong ?

thanks,

Pierre
 
T

Thomas Tutone

Pierre said:
Hi,

after reading the article " The Standard Librarian : Defining Iterators
and Const Iterators" from Matt Austern:
http://www.ddj.com/showArticle.jhtml;jsessionid=41JODBZDWEMBYQSNDLOSKH0CJUNN2JVN?articleID=184401331

I wanted to test using the non-template function friends of template
classes. So I devised this code:

===8<======8<======8<======8<======8<======8<======8<===

#include <iostream>

using namespace std;

template <class T>
struct S
{

friend S foo( const S& s1, const S& s2 )
{
return S( s1.s + s2.s );
}

friend T operator+( const T& a, const S& s )
{

Try adding the following two lines here:

cout << "[In operator+]";
cout.flush();
return a+s.s;
}

friend ostream& operator<<( ostream& s, const S& o )
{
s << "S(" << o.s << ")";
return s;
}

S( T a ) : s( a ) {}

T s;
};

int main()
{
S<int> s1( 1 );
S<S<int> > s2( 10 );
cout << foo( s1, s2 );
cout << endl;
return 0;
}

===8<======8<======8<======8<======8<======8<======8<===

It does compile but segfaults at runtime o_O
Could someone explain to me what I did wrong ?

Add the two lines I indicated above, then re-compile and run your
program. I think you'll see the problem pretty quickly.

By the way, your program won't compile on Comeau, so I suspect your use
of templates is not correct. (But that is NOT the cause of your
described problem.)

Best regards,

Tom
 
P

Pierre Barbier de Reuille

Thomas said:
Pierre said:
Hi,

after reading the article " The Standard Librarian : Defining Iterators
and Const Iterators" from Matt Austern:
http://www.ddj.com/showArticle.jhtml;jsessionid=41JODBZDWEMBYQSNDLOSKH0CJUNN2JVN?articleID=184401331

I wanted to test using the non-template function friends of template
classes. So I devised this code:
[...]

It does compile but segfaults at runtime o_O
Could someone explain to me what I did wrong ?

Add the two lines I indicated above, then re-compile and run your
program. I think you'll see the problem pretty quickly.

By the way, your program won't compile on Comeau, so I suspect your use
of templates is not correct. (But that is NOT the cause of your
described problem.)

Best regards,

Tom



Thank you very much, I corrected the mistake ... Here is the code which
is working (I put only the class definition):


template <class T>
struct S
{

friend S foo( const S& s1, const S& s2 )
{
return S( s1.s + s2.s );
}

friend T operator+( const S& a, const T& s )
{
return a+s.s;
}

friend T operator+( const S& s1, const S& s2 )
{
return s1.s + s2.s;
}

friend ostream& operator<<( ostream& s, const S& o )
{
s << "S(" << o.s << ")";
return s;
}

S( T a ) : s( a ) {}

T s;
};


As for the correctness, I think it *is* correct. At least, the use of
the non-template friend functions is even explicitly allowed by the norm
(cf. the article which even gives the precise § in the norm).
However, if you could give me the error, I would be very interested.

Thanks,

Pierre
 
T

Thomas Tutone

Pierre said:
Thank you very much, I corrected the mistake ... Here is the code which
is working (I put only the class definition):


template <class T>
struct S
{

friend S foo( const S& s1, const S& s2 )
{
return S( s1.s + s2.s );
}

friend T operator+( const S& a, const T& s )
{
return a+s.s;
}

friend T operator+( const S& s1, const S& s2 )
{
return s1.s + s2.s;
}

friend ostream& operator<<( ostream& s, const S& o )
{
s << "S(" << o.s << ")";
return s;
}

S( T a ) : s( a ) {}

T s;
};


As for the correctness, I think it *is* correct. At least, the use of
the non-template friend functions is even explicitly allowed by the norm
(cf. the article which even gives the precise § in the norm).
However, if you could give me the error, I would be very interested.

Your code, as revised, compiles on Comeau without error. However, your
original code did not - see for yourself:

http://www.comeaucomputing.com/tryitout/

"ComeauTest.c", line 14: error: no operator "+" matches these
operands
operand types are: const S<int> + const S<int>
return S( s1.s + s2.s );
^
detected during instantiation of class "S<T> [with
T=S<int>]" at
line 45

1 error detected in the compilation of "ComeauTest.c".

As I said, you've now corrected the problem.

Best regards,

Tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,072
Latest member
trafficcone

Latest Threads

Top