By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,305 Members | 1,822 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,305 IT Pros & Developers. It's quick & easy.

template parameter friend, it this valid ?

P: n/a
The code below compiles on gcc 3.4.0 and Comeau's 4.3.3 but MSVC++ 7.1
dies complaining about somthing <unknown>.

Is this valid ?

More to the point, is there any way of doing this that is supported
across all 3 compilers ? I want a template to take a parameter and
make it it's friend.

<code>
struct x
{
template <typename T>
static void X( T t )
{
delete t;
}
};
template <typename T=x>
class Foo
{
template <typename T2>
friend void T::X( T2 t );

~Foo(){}
public:

void FinishMe()
{
T::X( this );
}
};
int main()
{
Foo<> * zz = new Foo<>;

zz->FinishMe();
}
</code>
Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a

"Gianni Mariani" <gi*******@mariani.ws> wrote in message
news:48**************************@posting.google.c om...
The code below compiles on gcc 3.4.0 and Comeau's 4.3.3 but MSVC++ 7.1
dies complaining about somthing <unknown>.

Is this valid ?

More to the point, is there any way of doing this that is supported
across all 3 compilers ? I want a template to take a parameter and
make it it's friend.

<code>
struct x
{
template <typename T>
static void X( T t )
{
delete t;
}
};
template <typename T=x>
class Foo
{
template <typename T2>
friend void T::X( T2 t );

~Foo(){}
public:

void FinishMe()
{
T::X( this );
}
};
int main()
{
Foo<> * zz = new Foo<>;

zz->FinishMe();
}
</code>


I personally think MSVC can't do much well with templates. I have MSVC++ 6.0
and it dies when I do various things, such as including a #pragma in a
template definition (C1001: INTERNAL COMPILER ERROR, or compiler crashes,
depending on build settings).

Probably it's legal (I didn't get around to checking) but M$ is too stupid
to get around to fixing it (yes I'm a linux guy).

-- Matt
Jul 22 '05 #2

P: n/a
>
I personally think MSVC can't do much well with templates. I have MSVC++ 6.0 and it dies when I do various things, such as including a #pragma in a
template definition (C1001: INTERNAL COMPILER ERROR, or compiler crashes,
depending on build settings).

Gianni is talking about MSVC 7.1, which is much much better than MSVC 6 at
templates.
Probably it's legal (I didn't get around to checking) but M$ is too stupid
to get around to fixing it (yes I'm a linux guy).


Obviously you're so wrapped up in linux that you are unaware that MS have
'fixed it'. Why don't you try it out, seeing as it's free. I don't know
about #pragma in a template but you'll find most template code is handled
correctly and VC 7.1 is now one of the most standard compliant compilers
around.

john
Jul 22 '05 #3

P: n/a
gi*******@mariani.ws (Gianni Mariani) wrote in message news:<48**************************@posting.google. com>...
The code below compiles on gcc 3.4.0 and Comeau's 4.3.3 but MSVC++ 7.1
dies complaining about somthing <unknown>.

Is this valid ?


I believe that VC 2003 thinks that on that line, T is a type - not a
template parameter. I realize this doesn't help you much ...

Maybe my reasoning is bad, but I determined this after swapping x for
T --

friend void T::X( T2 t ); --> friend void x::X( T2 t );

-------------------------------------------------------
The following code builds fine with that little change:
--------------------------------------------------------

#include "stdafx.h"

struct x
{
template <typename T>
static void X( T t )
{
delete t;
}
};
template <typename T=x>
class Foo
{
template <typename T2>
friend void x::X( T2 t );

~Foo(){}
public:

void FinishMe()
{
T::X( this );
}
};
int _tmain(int argc, char** argv)
{
Foo<> * zz = new Foo<>;

zz->FinishMe();
}

-----------------------------------------------------------------------------
**** in fact, this simpler example breaks VC 2003 with the same error
and the same use of 'T' ****
-----------------------------------------------------------------------------

#include "stdafx.h"

struct x
{
static void X() { }
};

template <typename T>
class Foo
{
friend void T::X(); // <-- error C2063: '<Unknown>' : not a
function
};

int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}

------------------------------------------------------------------------------
* Using typedef's, one can work around the simpler problem I've
described - but that gets away from templates ... not sure what your
constraints are or if something like

template<class T> class Foo;
typedef void (*XTC)(Foo<x>*);
XTC xtc = x::X<Foo<x>* >;*
...

is even reasonable for you. I'm sure someone else may have a better
idea.
------------------------------------------------------------------------------

#include "stdafx.h"

struct x
{
static void X() { }
};

typedef void (*TX)();
TX tx = x::X;

template <typename T>
class Foo
{
friend void (tx)();
};

int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}

----------

Hth,

-Luther
Jul 22 '05 #4

P: n/a
Gianni Mariani wrote:

The code below compiles on gcc 3.4.0 and Comeau's 4.3.3 but MSVC++ 7.1
dies complaining about somthing <unknown>.

Is this valid ?

More to the point, is there any way of doing this that is supported
across all 3 compilers ? I want a template to take a parameter and
make it it's friend.

<code>
struct x
{
template <typename T>
static void X( T t )
{
delete t;
}
};

template <typename T=x>
class Foo
{
template <typename T2>
friend void T::X( T2 t );

~Foo(){}
public:

void FinishMe()
{
T::X( this );
}
};

int main()
{
Foo<> * zz = new Foo<>;

zz->FinishMe();
}
</code>

I couldn't find anything wrong with your example. For the record, it
compiles with gcc 3.3.3 too.

As to a work-around, perhaps an easier job for things like MSVC++ 7.1
would be to handle a non-member function template:

struct x {
};

template <class S, typename T>
void X(T t) {
delete t;
}
template <typename T=x>
class Foo
{
//assuming only this specialisation needs to be a friend:
friend void X<T, Foo*>(Foo*);

~Foo(){}
public:

void FinishMe()
{
X<T, Foo*>(this);
}
};

I think void X(T t) should be able to use whatever definitions of x (via the
template parameter S) it needs in the same way as in your original version.
Another alternative that compiles with gcc as well (not sure about MSVC)
is a template <typename T> struct x.

Denis
Jul 22 '05 #5

P: n/a
Gianni Mariani wrote:
The code below compiles on gcc 3.4.0 and Comeau's 4.3.3 but MSVC++ 7.1
dies complaining about somthing <unknown>.

Is this valid ?

More to the point, is there any way of doing this that is supported
across all 3 compilers ? I want a template to take a parameter and
make it it's friend.

.....

Thanks for the responses. It turns out that this is definitly an area
of weakness.

I also have a problem with somthing like:

template <typename T1>
struct A
{
friend class B;

private:
T1 x;
};
struct B
: A<int>
{

using A<int>::x;
};
VC7.1 does not like this.

Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.