template parameter friend, it this valid ?

G

Gianni Mariani

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>
 
M

Matthew Del Buono

Gianni Mariani said:
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
 
D

Denis Remezov

Gianni said:
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
 
J

John Harrison

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
 
L

Luther Baker

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;
}
 
G

Gianni Mariani

Gianni said:
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.
 

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,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top