Operator<<, in nested templated classes.

E

Eddie Parker

Hi!

I'm having an interesting problem that I can't seem to get to work, and
I'm curious if someone could either a) tell me how to make it work, or
b) tell me why it *can't* work. :)

Anyhow, here's a small test case that should compile on most compilers:

#include <iostream>

using namespace std;

template<typename T>
class TemplatedOuter
{
public:
class NestedInner
{
public:
int a;

NestedInner() : a(0) {};
};


TemplatedOuter() : m_NestedInner() {};

NestedInner m_NestedInner;
};

/**
* This does not.
*/
template<typename T>
ostream operator<<(ostream &os, typename TemplatedOuter<T>::NestedInner
const &nestedInner)
{
}

/**
* This works...
*/
template<typename T>
ostream operator<<(ostream &os, TemplatedOuter<T> const
&templatedOuter)
{
}

int main(void)
{
TemplatedOuter<int> a;

// This works.
cout << a;

// This does not.
cout << a.m_NestedInner;
}


/**

Output:

main.cpp: In function `int main()':
main.cpp:39: error: no match for 'operator<<' in 'std::cout <<
a.TemplatedOuter<int>::m_NestedInner'

*/

As you can see, I'm trying to basically have a nested public class, and
print out the contents of it... But it can't seem to find it... Any
suggestions on what I'm doing wrong, would be appreciated!

Thanks!
 
V

Victor Bazarov

Eddie said:
I'm having an interesting problem that I can't seem to get to work, and
I'm curious if someone could either a) tell me how to make it work, or
b) tell me why it *can't* work. :)

You're running into "non-deducible context". It's not possible to deduce
the template argument from a template nested class. What's happening is
this: you give 'a.m_NestedInner' from which 'T' is supposed to be deduced.
The list of deducible contexts does *not* include template-name said:
Anyhow, here's a small test case that should compile on most compilers:

#include <iostream>

using namespace std;

template<typename T>
class TemplatedOuter
{
public:
class NestedInner
{
public:
int a;

NestedInner() : a(0) {};

Drop the traling semicolon from the line above.
};


TemplatedOuter() : m_NestedInner() {};

Drop the traling semicolon from the line above.
NestedInner m_NestedInner;
};

/**
* This does not.
*/
template<typename T>
ostream operator<<(ostream &os, typename TemplatedOuter<T>::NestedInner
const &nestedInner)

{

return os;
}

/**
* This works...
*/
template<typename T>
ostream operator<<(ostream &os, TemplatedOuter<T> const

&templatedOuter)
{

return os;
}

int main(void)
{
TemplatedOuter<int> a;

// This works.
cout << a;

// This does not.
cout << a.m_NestedInner;
}


/**

Output:

main.cpp: In function `int main()':
main.cpp:39: error: no match for 'operator<<' in 'std::cout <<
a.TemplatedOuter<int>::m_NestedInner'

*/

As you can see, I'm trying to basically have a nested public class, and
print out the contents of it... But it can't seem to find it... Any
suggestions on what I'm doing wrong, would be appreciated!

The only work-around I know is to specify the template argument explicitly
in a call:

::eek:perator << <int> (cout, a.m_NestedInner);

Another work-around, of course, is to add a member function 'print' to the
'NestedInner' class and use it as

a.m_NestedInner.print(cout);

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top