User forums > Help

Templated friend function + gcc = hell

(1/2) > >>

FocusedWolf:
#include <iostream>

template <class Type>
class HateAnsi
{
   
public:

   HateAnsi()
   {}
   
   friend Type Something(Type k);
   
};

template <class Type>
Type Something(Type k)
{
   return k;
}

int main()
{
   std::cout << "Hello world!" << std::endl;
   return 0;
}

This doesn't work...in gcc...but does in vs.net (ansi is the devil),...so how do i get it to work?

I tried to figure this out, but all i keep finding on the web is peoples posts about how ansi is going against the guidlines or something...eh...

O and whatever the fix, the code has to compile in vs.net no matter what :P

mandrav:

--- Code: ---Compiling: C:\Devel\Untitled1.cpp
C:\Devel\Untitled1.cpp:12: warning: friend declaration `Type Something(Type)' declares a non-template function
C:\Devel\Untitled1.cpp:12: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning
Linking console executable: C:\Devel\Untitled1.exe
Process terminated with status 0 (0 minutes, 5 seconds)
0 errors, 2 warnings

--- End code ---

It is compiling fine (with a warning though). What do you mean it's not working?

byo:
Have You tried something like that ? (It compiles without warnings on GCC)


--- Code: ---#include <iostream>

template <class Type>
Type Something(Type k)
{
   return k;
}

template <class Type>
class HateAnsi
{

public:

   HateAnsi()
   {}

   friend Type Something<Type>(Type k);

};

int main()
{
   std::cout << "Hello world!" << std::endl;
   return 0;
}

--- End code ---

tiwag:

--- Code: ---#include <iostream>

template<long B,unsigned long E>
struct pow_helper
{
    static const double value;
};

template<long B,unsigned long E>
const double pow_helper<B,E>::value=B*pow_helper<B,E-1>::value;

template<long B>
struct pow_helper<B,0>
{
    static const double value;
};

template<long B>
const double pow_helper<B,0>::value=1;

template<long B,long E>
struct power
{
    static const double value;
};

template<long B,long E>
const double power<B,E>::value= E<0 ? 1.0/pow_helper<B,E<0 ? -E : E>::value :
                                pow_helper<B,E<0 ? -E : E>::value;

int main()
{
    std::cout << power<10,-3>::value << std::endl;
}

--- End code ---

or this sample compiles without warnings too and does something meaningful also ;-)

thomas:
Your code is ambiguous, and the compiler rightly tells you so (it even tells you what to do to avoid the warning).
You should rather blame vs.net for failing to see that.


--- Quote from: FocusedWolf on October 10, 2005, 06:12:10 am ---all i keep finding on the web is peoples posts about how ansi is going against the guidlines or something...eh...
--- End quote ---
"guiding declarations", not guidelines.

Try this (about half way down the page): http://www.artima.com/cppsource/simple2.html

--- Quote ---But wait a minute. Is operator<< here a template or not? And do I want it to befriend all specializations of Box or not? No conforming C++ compiler will let you instantiate the Box class and use the associated stream inserter.
--- End quote ---

I believe that compiler warnings are not a deliberate annoyance (although they sometimes seem to be), but they actually prevent you from shooting your foot. This is especially true if you do things that are ambiguous or may have undefined or unexpected results. These may work on one day and may not work on another.

Navigation

[0] Message Index

[#] Next page

Go to full version