Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   compiler error (http://www.velocityreviews.com/forums/t506297-compiler-error.html)

Aston Martin 05-14-2007 07:00 AM

compiler error
 
can anyone point out why compiler is not happy ? it finds ambiguity in
the friend function declaration and its implementation. if you
eliminate the 'dummy' template parameter altogether, it works. what
effect 'dummy' is having ? it is important to have the function as
friend, since so i can make SomeClass look-n-feel as builtin.

#include<iostream>
using namespace std;

template<typename T, int dummy>
class SomeClass
{
private:
T someVariable;

public:
SomeClass() : someVariable(65) {}
~SomeClass() {}

template<typename T, int dummy>
friend ostream& operator << ( ostream& outStream, const
SomeClass<T, dummy>& sc );
};

template<typename T, int dummy>
ostream& operator << ( ostream& outStream, const SomeClass<T, dummy>&
sc )
{
outStream << "someVariable: " << sc.someVariable << endl;
return outStream;
}

int main(int argc, char* argv[])
{
SomeClass<int,3> cl;
cout << cl;
return 0;
}


Zeppe 05-14-2007 08:26 AM

Re: compiler error
 
Aston Martin wrote:

> template<typename T, int dummy>
> friend ostream& operator << ( ostream& outStream, const
> SomeClass<T, dummy>& sc );


the function is not template. If it was so, anyway, you were hiding the
original templates names with this second template declaration.

the correct declaration of such a friend function is (with forward
references)

#include<iostream>
using namespace std;

template<typename T, int dummy>
class SomeClass;

template<typename T, int dummy>
ostream& operator << ( ostream& outStream, const SomeClass<T, dummy>& sc );

template<typename T, int dummy>
class SomeClass
{
private:
T someVariable;

public:
SomeClass() : someVariable(65) {}
~SomeClass() {}


friend ostream& operator << <> ( ostream& outStream, const
SomeClass<T, dummy>& sc );
};

template<typename T, int dummy>
ostream& operator << ( ostream& outStream, const SomeClass<T, dummy>&
sc )
{
outStream << "someVariable: " << sc.someVariable << endl;
return outStream;
}

int main(int argc, char* argv[])
{
SomeClass<int,3> cl;
cout << cl;
return 0;
}

Regards,

Zeppe

Aston Martin 05-14-2007 09:06 AM

Re: compiler error
 
On May 14, 1:26 pm, Zeppe
<zeppe@.remove.all.this.long.comment.email.it> wrote:
> Aston Martin wrote:
> > template<typename T, int dummy>
> > friend ostream& operator << ( ostream& outStream, const
> > SomeClass<T, dummy>& sc );

>
> the function is not template. If it was so, anyway, you were hiding the
> original templates names with this second template declaration.
>
> the correct declaration of such a friend function is (with forward
> references)
>
> #include<iostream>
> using namespace std;


Hello Zeppe, thanks for your advise, I see your point, but also
disappointed that even this does give exactly the same error

#include<iostream>
using namespace std;

template<typename T, int dummy>
class SomeClass;

template<typename T, int dummy>
ostream& operator << ( ostream& outStream, const SomeClass<T, dummy>&
sc )
{
outStream << "someVariable: " << sc.someVariable << endl;
return outStream;
}

template<typename T, int dummy>
class SomeClass
{
private:
T someVariable;

public:
SomeClass() : someVariable(65) {}
~SomeClass() {}

template<typename T, int dummy>
friend ostream& operator << ( ostream& outStream, const
SomeClass<T, dummy>& sc );
};

int main(int argc, char* argv[])
{
SomeClass<int,3> cl;
cout << cl;
return 0;
}


Salt_Peter 05-14-2007 12:25 PM

Re: compiler error
 
On May 14, 5:06 am, Aston Martin <masoom.sha...@gmail.com> wrote:
> On May 14, 1:26 pm, Zeppe
>
> <zeppe@.remove.all.this.long.comment.email.it> wrote:
> > Aston Martin wrote:
> > > template<typename T, int dummy>
> > > friend ostream& operator << ( ostream& outStream, const
> > > SomeClass<T, dummy>& sc );

>
> > the function is not template. If it was so, anyway, you were hiding the
> > original templates names with this second template declaration.

>
> > the correct declaration of such a friend function is (with forward
> > references)

>
> > #include<iostream>
> > using namespace std;

>
> Hello Zeppe, thanks for your advise, I see your point, but also
> disappointed that even this does give exactly the same error


and it should, since you are redeclaring the template parameters.
Perhaps this might explain it better:

int main()
{
int n = 99;
int n = 0; // why is that not allowed?
}

>
> #include<iostream>
> using namespace std;
>
> template<typename T, int dummy>
> class SomeClass;
>
> template<typename T, int dummy>
> ostream& operator << ( ostream& outStream, const SomeClass<T, dummy>&
> sc )
> {
> outStream << "someVariable: " << sc.someVariable << endl;
> return outStream;
>
> }
>
> template<typename T, int dummy>
> class SomeClass
> {
> private:
> T someVariable;
>
> public:
> SomeClass() : someVariable(65) {}
> ~SomeClass() {}
>
> template<typename T, int dummy>
> friend ostream& operator << ( ostream& outStream, const
> SomeClass<T, dummy>& sc );


The error tells you what you did wrong. typename T and int dummy are
redeclared.

template<typename U, int Dummy>
friend ostream&
operator << ( ostream& outStream,
const SomeClass<U, Dummy>& sc );

....or...

friend ostream&
operator << < > ( ostream& outStream,
const SomeClass<T, dummy>& sc );

>
> };
>
> int main(int argc, char* argv[])
> {
> SomeClass<int,3> cl;
> cout << cl;
> return 0;
>
> }




Zeppe 05-14-2007 12:52 PM

Re: compiler error
 
Aston Martin wrote:

> Hello Zeppe, thanks for your advise, I see your point, but also
> disappointed that even this does give exactly the same error
>
> #include<iostream>
> using namespace std;
>
> template<typename T, int dummy>
> class SomeClass;
>
> template<typename T, int dummy>
> ostream& operator << ( ostream& outStream, const SomeClass<T, dummy>&
> sc )
> {
> outStream << "someVariable: " << sc.someVariable << endl;
> return outStream;
> }
>
> template<typename T, int dummy>
> class SomeClass
> {
> private:
> T someVariable;
>
> public:
> SomeClass() : someVariable(65) {}
> ~SomeClass() {}
>
> template<typename T, int dummy>
> friend ostream& operator << ( ostream& outStream, const
> SomeClass<T, dummy>& sc );


you are declaring again your function as a template, while it is not. I
mean, the function is a template on the parameters of SomeClass, but you
don't want to declare the general template function as a friend of
SomeClass<T,dummy>. You want to declare only the function operator<<
<T,dummy>(...) as a friend of SomeClass<T,dummy>. That's way you have to
remove the template from the friend declaration:


friend ostream& operator << <> ( ostream& outStream, const
SomeClass<T, dummy>& sc );

If you wanted to make the generic template class as friend, you have to
change the names of the templates:

template<typename T1, int dummy1>
friend ostream& operator << ( ostream& outStream, const
SomeClass<T1, dummy1>& sc );

but there is no point to make the generic template function as a friend.
It's always good to reduce the scope of the friend as much as possible,
because friend is evil, in general.


Regards,

Zeppe

Aston Martin 05-14-2007 01:36 PM

Re: compiler error
 
> but there is no point to make the generic template function as a friend.
> It's always good to reduce the scope of the friend as much as possible,
> because friend is evil, in general.
>
> Regards,
>
> Zeppe


Salt_Peter, Zeppe

I understand what you said. It was re-declaration and function is
expected to 're-use' class template parameters. I had guessed so and
tried version below, which works. I just wanted to know that how to
give body(provide definition) to

friend ostream& operator << ( ostream& outStream, const SomeClass<T,
dummy>& sc );

declared in SomeClass<T,dummy>, outside class(see commented code).
linker complains if you declare in class and provide implementation
outside. or is it the only possible way to go.

#include<iostream>
using namespace std;

template<typename T, int dummy>
class SomeClass
{
private:
T someVariable;

public:
SomeClass() : someVariable(65) {}
~SomeClass() {}

friend ostream& operator << ( ostream& outStream, const
SomeClass<T, dummy>& sc )
{
outStream << sc.someVariable;
return outStream;
}
};

int main(int argc, char* argv[])
{
SomeClass<int,3> cl;
cout << cl;
return 0;
}

//template<typename T, int dummy>
//ostream& operator << ( ostream& outStream, const SomeClass<T,
dummy>& sc )
//{
// outStream << "someVariable: " << sc.someVariable << endl;
// return outStream;
//}


Salt_Peter 05-14-2007 08:08 PM

Re: compiler error
 
On May 14, 9:36 am, Aston Martin <masoom.sha...@gmail.com> wrote:
> > but there is no point to make the generic template function as a friend.
> > It's always good to reduce the scope of the friend as much as possible,
> > because friend is evil, in general.

>
> > Regards,

>
> > Zeppe

>
> Salt_Peter, Zeppe
>
> I understand what you said. It was re-declaration and function is
> expected to 're-use' class template parameters. I had guessed so and
> tried version below, which works. I just wanted to know that how to
> give body(provide definition) to
>
> friend ostream& operator << ( ostream& outStream, const SomeClass<T,
> dummy>& sc );
>
> declared in SomeClass<T,dummy>, outside class(see commented code).
> linker complains if you declare in class and provide implementation
> outside. or is it the only possible way to go.


The linker complains because your declaration is wrong. Do you see the
'< >' to indicate that the operator is indeed a template
specialization of Someclass<T,dummy>? Look harder.

template<typename T, int dummy>
class SomeClass
{
...
friend ostream&
operator<< < > ( ostream&, const SomeClass<T, dummy>& );
};

template<typename T, int dummy>
ostream& operator << ( ostream& outStream,
const SomeClass<T, dummy>& sc )
{
outStream << "someVariable: " << sc.someVariable << endl;
return outStream;

}

And Zeppe is right when he says:
You want to declare only the function operator<< <T,dummy>(...) as a
friend of SomeClass<T,dummy>. Thats why you need ... operator<< < >
(...);


James Kanze 05-15-2007 09:13 AM

Re: compiler error
 
On May 14, 2:52 pm, Zeppe
<zeppe@.remove.all.this.long.comment.email.it> wrote:
> Aston Martin wrote:


> > Hello Zeppe, thanks for your advise, I see your point, but also
> > disappointed that even this does give exactly the same error


> > #include<iostream>
> > using namespace std;


> > template<typename T, int dummy>
> > class SomeClass;


> > template<typename T, int dummy>
> > ostream& operator << ( ostream& outStream, const SomeClass<T, dummy>&
> > sc )
> > {
> > outStream << "someVariable: " << sc.someVariable << endl;
> > return outStream;
> > }


> > template<typename T, int dummy>
> > class SomeClass
> > {
> > private:
> > T someVariable;


> > public:
> > SomeClass() : someVariable(65) {}
> > ~SomeClass() {}


> > template<typename T, int dummy>
> > friend ostream& operator << ( ostream& outStream, const
> > SomeClass<T, dummy>& sc );


> you are declaring again your function as a template, while it is not. I
> mean, the function is a template on the parameters of SomeClass, but you
> don't want to declare the general template function as a friend of
> SomeClass<T,dummy>. You want to declare only the function operator<<
> <T,dummy>(...) as a friend of SomeClass<T,dummy>. That's way you have to
> remove the template from the friend declaration:


> friend ostream& operator << <> ( ostream& outStream, const
> SomeClass<T, dummy>& sc );


Does this work with all compilers today? (And does it declare
all template instantiations as friend, or just the relevant
one?)

My usual solution is:

template< typename T, int dummy >
class SomeClass
{
std::ostream& print( std::ostream& dest ) const ;
// member function, no problem...
friend std::ostream& operator<<( std::ostream& dest,
SomeClass const& obj )
{
return obj.print( dest ) ;
}
// ...
} ;

By putting the implementation of the (non template) function
inline, I get a new version of it---the one I need---every time
I instantiate the class.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Zeppe 05-15-2007 10:43 AM

Re: compiler error
 
James Kanze wrote:
> On May 14, 2:52 pm, Zeppe
> <zeppe@.remove.all.this.long.comment.email.it> wrote:
>> friend ostream& operator << <> ( ostream& outStream, const
>> SomeClass<T, dummy>& sc );

>
> Does this work with all compilers today? (And does it declare
> all template instantiations as friend, or just the relevant
> one?)


well, I don't know if it does work with all the compilers. It works on
vc8, g++ 4.1 and g++ 3.4 for sure, because I tried it. It declares only
the relevant function as friend.

> My usual solution is:
>
> template< typename T, int dummy >
> class SomeClass
> {
> std::ostream& print( std::ostream& dest ) const ;
> // member function, no problem...
> friend std::ostream& operator<<( std::ostream& dest,
> SomeClass const& obj )
> {
> return obj.print( dest ) ;
> }
> // ...


In my opinion your solution is much more elegant. You can also avoid
friend if you put your print public, given that is a safe function (even
if it complicates without reason the public interface of the class).
Usually in my case, when the classes haven't got the getters for all the
parameters that I want to show (that is not so common), I go for a
solution similar to yours, and if the performances are not a problem and
it makes sense, I create a 'std::string toString()' public method
without friend that will be called by operator<<.

Regards,

Zeppe

Aston Martin 05-15-2007 12:23 PM

Re: compiler error
 
> And Zeppe is right when he says:
> You want to declare only the function operator<< <T,dummy>(...) as a
> friend of SomeClass<T,dummy>. Thats why you need ... operator<< < >
> (...);


Salt_peter,

thanks again. I learnt something. but did u build before posting ?
since for me linker still fails linkage!!
yeah, I looked harder and found "< >' :) and declared the function as
below

friend ostream& operator << < >( ostream& outStream, const
SomeClass<T, dummy>& sc );

~Aston



All times are GMT. The time now is 11:51 PM.

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