template friends

N

Noah Roberts

template < typename V >
class Outer
{
public:
template < typename T >
class Inner
{
private:
template <class> friend class Inner;
};

typedef Inner<V> Test;

Test test() { return Test(); }
};

int main()
{
Outer<int> outer;
Outer<int>::Test t = outer.test();
}

1>c:\documents and settings\nroberts\my documents\visual studio
2005\projects\playground\playground\playground.cpp(17) : error C3855:
'Outer<V>::Inner': template parameter 'T' is incompatible with the
declaration

This compiles so long as Outer is not a template. I'm uncertain of
templated friend syntax. How do I change the friend statement to
reflect the change to Outer from basic class to template? Tried the
following rejected attempts:


template <class> friend typename Outer<V>::Inner;
template <class> friend class typename Outer<V>::Inner;

thanks.
 
G

Gianni Mariani

Noah Roberts wrote:
....
This compiles so long as Outer is not a template. I'm uncertain of
templated friend syntax. How do I change the friend statement to
reflect the change to Outer from basic class to template? Tried the
following rejected attempts:


template <class> friend typename Outer<V>::Inner;
template <class> friend class typename Outer<V>::Inner;

I can't see anything wrong with your code. FYI, it compiles fine on
gcc3.4.4 and gcc4.1.1.

Sounds like a VS2005 bug.
 
G

Gianni Mariani

Gianni said:
Noah Roberts wrote:
...

I can't see anything wrong with your code. FYI, it compiles fine on
gcc3.4.4 and gcc4.1.1.

Sounds like a VS2005 bug.

Just to make sure I wasn't smoking - this compiles on gcc4.1.1 (not on
either VS2005 or gcc3.4.4).

template < typename V >
class Outer
{
public:
template < typename T >
class Inner
{
template < typename X > template < typename > friend class
Outer<X>::Inner;

int y;
public:
template < typename X, typename Y >
int f( typename Outer<X>::template Inner<Y> boo )
{
return boo.y;
}
};

typedef Inner<V> Test;

Test test() { return Test(); }

};

int main()
{
Outer<int> outer;
Outer<char> out2;
Outer<int>::Test t = outer.test();

out2.test().f<int,int>( outer.test() );
}
 
A

amparikh

Noah said:
template < typename V >
class Outer
{
public:
template < typename T >
class Inner
{
private:
template <class> friend class Inner;
};

typedef Inner<V> Test;

Test test() { return Test(); }
};

int main()
{
Outer<int> outer;
Outer<int>::Test t = outer.test();
}

1>c:\documents and settings\nroberts\my documents\visual studio
2005\projects\playground\playground\playground.cpp(17) : error C3855:
'Outer<V>::Inner': template parameter 'T' is incompatible with the
declaration

This compiles so long as Outer is not a template. I'm uncertain of
templated friend syntax. How do I change the friend statement to
reflect the change to Outer from basic class to template? Tried the
following rejected attempts:

Comeau also gives the same error.
template <class> friend typename Outer<V>::Inner;
template <class> friend class typename Outer<V>::Inner;

I think within the scope of a template Class C, C<T> is equivalent to C
I think.

Therefore you can just try the following and it should work.
friend class Inner;
 
N

Noah Roberts

Gianni said:
Just to make sure I wasn't smoking - this compiles on gcc4.1.1 (not on
either VS2005 or gcc3.4.4).

How about something closer to what I am trying to accomplish:

template < typename V >
class Outer
{
public:
template < typename T >
class Inner
{
private:
template <typename> friend class Inner;

int y;

template < typename Y >
int f(typename Outer::template Inner<Y> boo) const
{
return boo.y;
}
};

typedef Inner<V> Test;
typedef Inner<V const> cTest;

Test test() { return Test(); }
cTest ctest() { return cTest(); }
};

int main()
{
Outer<int> outer;

outer.test().f( outer.ctest());
}


VS complains like it did before about the friendship declaration, g++
3.4.5 complains that y is private in the context of f. The gnu
compiler does ok as long as f isn't attempted.

I also tried to declare f with:
template < typename Y > int f(Inner<Y> boo) ...

Same error in g++, vs adds an unresolvable template argument error.

You think this is the correct way to do what I'm trying to do though,
huh?
 
N

Noah Roberts

Noah said:
template < typename V >
class Outer
{
public:
template < typename T >
class Inner
{
private:
template <typename> friend class Inner;

int y;

template < typename Y >
int f(typename Outer::template Inner<Y> boo) const
{
return boo.y;
}
};
VS complains like it did before about the friendship declaration, g++
3.4.5 complains that y is private in the context of f. The gnu
compiler does ok as long as f isn't attempted.

Geesh. Of course there is an access issue. f is private. Making f
public causes the code to compile and work in g++ 3.4.5. Testing w/
comeau still pukes up on the friend line though with:

"ComeauTest.c", line 10: error: template nesting depth does not match
the previous
declaration of class template "Outer<V>::Inner [with V=int]"
template <typename> friend class Inner;
^
detected during instantiation of class
"Outer<V>::Inner<T> [with V=int, T=int]" at line 33
 
N

Noah Roberts

Comeau also gives the same error.

thanks for the idea.
I think within the scope of a template Class C, C<T> is equivalent to C
I think.

Yes, I know but I was just trying different things that had some sense
to them.
Therefore you can just try the following and it should work.
friend class Inner;

That does work is msvc but not in g++. comeau agrees with g++.

I don't want to make myself a friend, I want other instances of this
template to be friends. So Inner<V> and Inner<V const> would be
friends.
 
G

Gianni Mariani

Noah Roberts wrote:
....
VS complains like it did before about the friendship declaration, g++
3.4.5 complains that y is private in the context of f. The gnu
compiler does ok as long as f isn't attempted.

Geesh. Of course there is an access issue. f is private. Making f
public causes the code to compile and work in g++ 3.4.5. Testing w/
comeau still pukes up on the friend line though with:

"ComeauTest.c", line 10: error: template nesting depth does not match
the previous
declaration of class template "Outer<V>::Inner [with V=int]"
template <typename> friend class Inner;
^
detected during instantiation of class
"Outer<V>::Inner<T> [with V=int, T=int]" at line 33

Yes - it seems like a "rejects valid" but. I sent a note to Greg.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top