Connecting Tech Pros Worldwide Forums | Help | Site Map

Operator<<, in nested templated classes.

Eddie Parker
Guest
 
Posts: n/a
#1: Sep 9 '05
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!

Victor Bazarov
Guest
 
Posts: n/a
#2: Sep 9 '05

re: Operator<<, in nested templated classes.


Eddie Parker wrote:[color=blue]
> 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. :)[/color]

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<T>::type.
[color=blue]
> 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) {};[/color]

Drop the traling semicolon from the line above.
[color=blue]
> };
>
>
> TemplatedOuter() : m_NestedInner() {};[/color]

Drop the traling semicolon from the line above.
[color=blue]
>
> NestedInner m_NestedInner;
> };
>
> /**
> * This does not.
> */
> template<typename T>
> ostream operator<<(ostream &os, typename TemplatedOuter<T>::NestedInner
> const &nestedInner)[/color]

template<typename T>
ostream& ...
[color=blue]
> {[/color]

return os;
[color=blue]
> }
>
> /**
> * This works...
> */
> template<typename T>
> ostream operator<<(ostream &os, TemplatedOuter<T> const[/color]

template<typename T>
ostream& ...
[color=blue]
> &templatedOuter)
> {[/color]

return os;
[color=blue]
> }
>
> 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![/color]

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

::operator << <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
Closed Thread