Howto declare a friend function to a nested class

J

jdurancomas

Dear all,

I'm trying to declare the operator++ to a nested class. The nested
class is not template but the container it is.

The code used in teh sample program is included bellow:


#include <iostream>


template <class T>
class A
{
public:
class B;
};


template <class T>
bool operator == <T> (const A<T>::B &b1,
const class A<T>::B &b2);


template <class T>
class A<T>::B
{
public:
B(int a);

friend bool operator ==<> (const A<T>::B &b1, const A<T>::B &b2);

private:
int aa;
B b;
};


template <class T>
A<T>::B::B(int a):
aa(a)
{}


template <class T>
bool operator == <>(const A<T>::B& b1, const A<T>::B& b2)
{
return b1.aa == b2.aa;
}


class C {};


int main()
{
A<C> ac;

A<C>::B b1(4), b2(5);

bool res = (b1 == b2);
return 0;
}


I'm compiling with gcc version 4.1.2. The output of the compiler is
included bellow:

nested.cpp:13: error: expected initializer before '<' token
nested.cpp:23: error: expected unqualified-id before 'template'
nested.cpp:38: error: expected initializer before '<' token
nested.cpp: In instantiation of 'A<C>::B':
nested.cpp:51: instantiated from here
nested.cpp:27: error: 'A<T>::B::b' has incomplete type
nested.cpp:19: error: declaration of 'class A<C>::B'
nested.cpp: In function 'int main()':
nested.cpp:53: error: no match for 'operator==' in 'b1 == b2'

Any help will be appreciated.

Thanks and Best Regards,
Joaquim Duran
 
V

Victor Bazarov

[..]
template <class T>
class A<T>::B
{
public:
B(int a);

friend bool operator ==<> (const A<T>::B &b1, const A<T>::B &b2);

private:
int aa;
B b;

Am I reading this right? An instance of your 'B' class contains
another instance of the same class, 'b'? Not gonna work.

Fix this first, then post the corrected code again.

And keep in mind that a member of a class template _is_ essentially
a template itself.

V
 
A

Alf P. Steinbach

* (e-mail address removed):
Dear all,

I'm trying to declare the operator++ to a nested class. The nested
class is not template but the container it is.

The code used in teh sample program is included bellow:


#include <iostream>


template <class T>
class A
{
public:
class B;
};


template <class T>
bool operator == <T> (const A<T>::B &b1,
const class A<T>::B &b2);


template <class T>
class A<T>::B
{
public:
B(int a);

friend bool operator ==<> (const A<T>::B &b1, const A<T>::B &b2);

private:
int aa;
B b;
};


template <class T>
A<T>::B::B(int a):
aa(a)
{}


template <class T>
bool operator == <>(const A<T>::B& b1, const A<T>::B& b2)
{
return b1.aa == b2.aa;
}


class C {};


int main()
{
A<C> ac;

A<C>::B b1(4), b2(5);

bool res = (b1 == b2);
return 0;
}


I'm compiling with gcc version 4.1.2. The output of the compiler is
included bellow:

nested.cpp:13: error: expected initializer before '<' token
nested.cpp:23: error: expected unqualified-id before 'template'
nested.cpp:38: error: expected initializer before '<' token
nested.cpp: In instantiation of 'A<C>::B':
nested.cpp:51: instantiated from here
nested.cpp:27: error: 'A<T>::B::b' has incomplete type
nested.cpp:19: error: declaration of 'class A<C>::B'
nested.cpp: In function 'int main()':
nested.cpp:53: error: no match for 'operator==' in 'b1 == b2'

Any help will be appreciated.

Add "typename" before the dependent types.

Cheers, & hth.,

- Alf
 
J

jdurancomas

[..]
template <class T>
class A<T>::B
{
public:
B(int a);
friend bool operator ==<> (const A<T>::B &b1, const A<T>::B &b2);
private:
int aa;
B b;

Am I reading this right? An instance of your 'B' class contains
another instance of the same class, 'b'? Not gonna work.

Fix this first, then post the corrected code again.

And keep in mind that a member of a class template _is_ essentially
a template itself.

V

I agree, in the sample, I've declared a recursive type that C++ is not
supporting. I've removed it, and I've improved the syntax (adding
typename as suggested, thanks). Now, the only error is the declaration
of a friend template function.


Improved source code:

#include <iostream>


template <typename T>
class A
{
public:
class B;
};


/* Example of template function */
template <typename T>
T add(T a, T b) {return a+b;}


template <typename T>
bool operator == (const typename A<T>::B &b1,
const typename A<T>::B &b2);


template <typename T>
class A<T>::B
{
public:
B(int a);

friend bool operator == <> (const typename A<T>::B &b1,
const typename A<T>::B &b2); // Line 29

private:
int aa;
};


template <typename T>
A<T>::B::B(int a):
aa(a)
{}


template <typename T>
bool operator == (const typename A<T>::B& b1,
const typename A<T>::B& b2)
{
return b1.aa == b2.aa;
}


class C {};


int main()
{
A<C>::B b1(4), b2(5);

bool res = (b1 == b2); // Line 57
return 0;
}


The message error from compiler is:

nested.cpp: In instantiation of 'A<C>::B':
nested.cpp:55: instantiated from here
nested.cpp:29: error: template-id 'operator==<>' for 'bool
operator==(const A<C>::B&, const A<C>::B&)' does not match any
template declaration
nested.cpp: In function 'int main()':
nested.cpp:57: error: no match for 'operator==' in 'b1 == b2'

I've googled a litle abut how declare template functions as friends,
and It looks likes that the current syntax is right.

Thanks and Best Regads,
Joaquim Duran
 
V

Victor Bazarov

[...]
Improved source code:

#include <iostream>


template <typename T>
class A
{
public:
class B;
};


/* Example of template function */
template <typename T>
T add(T a, T b) {return a+b;}


template <typename T>
bool operator == (const typename A<T>::B &b1,
const typename A<T>::B &b2);


template <typename T>
class A<T>::B
{
public:
B(int a);

friend bool operator == <> (const typename A<T>::B &b1,

Should be

friend bool operator == said:
const typename A<T>::B &b2); // Line 29

private:
int aa;
};


template <typename T>
A<T>::B::B(int a):
aa(a)
{}


template <typename T>
bool operator == (const typename A<T>::B& b1,
const typename A<T>::B& b2)
{
return b1.aa == b2.aa;
}


class C {};


int main()
{
A<C>::B b1(4), b2(5);

bool res = (b1 == b2); // Line 57

There is no way for the compiler to determine that the template
operator should be used because from the expression 'b1 == b2'
the compiler cannot deduce the 'C' for the template -- the context
is not one of the deducible contexts.
return 0;
}


The message error from compiler is:

nested.cpp: In instantiation of 'A<C>::B':
nested.cpp:55: instantiated from here
nested.cpp:29: error: template-id 'operator==<>' for 'bool
operator==(const A<C>::B&, const A<C>::B&)' does not match any
template declaration

That can be rectified by placing 'T' in the angle brackets, see
above.
nested.cpp: In function 'int main()':
nested.cpp:57: error: no match for 'operator==' in 'b1 == b2'

This cannot be corrected because the compiler canno deduce the 'T'
for the template operator==
I've googled a litle abut how declare template functions as friends,
and It looks likes that the current syntax is right.

Apparently it wasn't.

V
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top