Re: OK in Visual C++6.0 but not in Visual C++ .NET 2003?

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance

From: Antti Keskinen (antti.keskinen_at_REMOVEME.ee.tpu.fi)
Date: 02/06/05


Date: Sun, 6 Feb 2005 22:14:50 +0200

Hi !

The example you showed declared function template to be a friend of a class
template, correct ?

However, consider the following:

template<typename T>
class MyClass
{
    friend void InitClass(MyClass<T>& refClass);
};

void InitClass(MyClass<T>& ref)
{
}

I believe this would result in an error with 'undefined variable T', yes ?
Would it be correct to move the function definition above the class
definition, mark it as a templated function, and forward-declare the class
template, like in

template<typename T>
class MyClass;

template<typename T>
void InitClass(MyClass<T>& refClass)
{
}

template<typename T>
class MyClass
{
    friend void InitClass(MyClass<T>& refClass);
};

This would be the same thing you did, but with different semantics, no ? How
would you tackle the situation of "declaring/defining a non-templated
function, which takes an instantated MyClass of any type as a parameter" ?
Or is this impossible due to the fact that non-templated functions cannot
take "any type" parameters ? If it's a non-templated function, is the only
possibility to declare it for a defined set of types, as in:

template<typename T>
class MyClass
{
    friend void InitClass(MyClass<T>& refClass);
};

void InitClass(MyClass<int>& refClass)
{
}

void InitClass(MyClass<double>& refClass)
{
}

void InitClass(MyClass<char>& refClass)
{
}

This would result in InitClass being a friend of MyClass<T> in cases where T
was of 'int', 'double' or 'long' type, but in other cases it would not be a
friend, correct ?

I know this sounds difficult and might feel irrelevant, but I'm just
intrigued by the template semantics, i.e. what does it actually mean to use
a template :)

-Antti Keskinen

"Carl Daniel [VC++ MVP]" <cpdaniel_remove_this_and_nospam@mvps.org.nospam>
wrote in message news:eZF2L6FDFHA.2540@TK2MSFTNGP09.phx.gbl...
> hihaho wrote:
> The problem is that your code isn't standard compliant so it shouldn't
> compile.
>
> When you write
>
> template <class T>
> class X
> {
> friend void f(X<T>&);
> };
>
> you're declaring a namespace-scoped non-template function f(X<T>&) as a
> friend.
>
> When you subsequently write (you didn't show this, but I'm betting this is
> what you did)
>
> template <class T>
> void f(X<T>&)
> {
> }
>
> You're defining a template function. Under VC7 and before, the compiler
> could not distinguish between instantiations of a template function like
> the above and a non-template function with the same signature, so your
> code "worked".
>
> An example:
>
> X<int> declares f(X<int>&) as a friend. VC6 could not tell the difference
> between the <int> instantiation of a function template:
>
> void f<int>(X<int>&);
>
> and a non-template function
>
> void f(X<int>&);
>
> VC7.1 (.NET 2003) fixes this compiler bug, which breaks your code. So,
> what are you to do? You have to declare your friend a little differently
> in order to declare am instantiation of a function template as a friend:
>
> // forward-declare the class template
> template <class T> class X;
>
> // forward-declare the function template
> template <class T> void f(X<T>&);
>
> // actual class definition
> template <class T>
> class X
> {
> friend void f<T>(X&);
> };
>
> // actual function definition
> template <class T>
> void f(X<T>&)
> {
> }
>
> This makes f<T>(X<T>&) a friend of X<T>. It doesn't make any like-named
> non-template functions friends, it also doesn't make f<U>(X<T>&) a friend
> of X<T> (only instantiations with the same template argument list are
> friend).
>
> HTH
>
> -cd
>
>



Relevant Pages

  • Re: Problem overriding >> and << in a template class
    ... the rejection also mentioned the cause the of problem: ... For the friend functions to work correctly you need to declare them ... to use a template argument list in the friend declaration. ...
    (comp.lang.cpp)
  • Re: template -> instance -> function unresolved ???
    ... friend template function accessing private data in the template. ... i compile this into a dll (yes i know, there is no exported function from ... have to declare the function before the class who's friend it is supposed ...
    (microsoft.public.vc.language)
  • Re: Circular Class Template Friendship
    ... > My issue is the syntax of declaring a friend class within ... > which the string is a fixed width that is specialized. ... it is still possible to have Name_Id_Table template ... the friend class declaration. ...
    (comp.lang.cpp)
  • Re: Class templates and friend function templates
    ... > It never occurred to me that the friend declaration could be an overload. ... > template ... I suspect the online version uses an EDG option to "instantiate ...
    (microsoft.public.vc.language)
  • Re: Template friendship to nested template class
    ... friend struct INNER; ... Probably you are missing an EXTRA template to declare ... I think it's because the name referred to in a 'friend' declaration is looked up to exist at the namespace scope. ...
    (microsoft.public.vc.language)