Connecting Tech Pros Worldwide Forums | Help | Site Map

stream operator of a class nested in a class template

Ares Lagae
Guest
 
Posts: n/a
#1: Oct 20 '08
How is an output stream operator of a class nested in a class template
defined? The code fragment below does not compile. Maybe it's just me,
but I don't see why it should not compile.

Best regards,

#include <iostream>

template <typename T>
struct foo
{
struct bar {};
bar bar_;
const bar& get_bar() const { return bar_; }
};

template <typename Ch, typename Tr, typename T>
std::basic_ostream<Ch,Tr>& operator<<(std::basic_ostream<Ch,Tr>&
ostream, typename foo<T>::bar&)
{
return ostream;
}

int main()
{
foo<intf;
const foo<int>::bar& b = f.get_bar();
std::cout << b << "\n";
}

Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for
ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 21: error: no operator "<<" matches these
operands
operand types are: std::ostream << const foo<int>::bar
std::cout << b << "\n";
^

1 error detected in the compilation of "ComeauTest.c".

Victor Bazarov
Guest
 
Posts: n/a
#2: Oct 20 '08

re: stream operator of a class nested in a class template


Ares Lagae wrote:
Quote:
How is an output stream operator of a class nested in a class template
defined? The code fragment below does not compile. Maybe it's just me,
but I don't see why it should not compile.
>
Best regards,
>
#include <iostream>
>
template <typename T>
struct foo
{
struct bar {};
bar bar_;
const bar& get_bar() const { return bar_; }
};
>
template <typename Ch, typename Tr, typename T>
std::basic_ostream<Ch,Tr>& operator<<(std::basic_ostream<Ch,Tr>&
ostream, typename foo<T>::bar&)
^^^^^^^^^^^^^^^^^^^^^
Your argument is declared non-const here, but you pass a const ref.

Also, this is a non-deducible context. You will need to be explicit to
specify the 'T' template argument.
Quote:
{
return ostream;
}
>
int main()
{
foo<intf;
const foo<int>::bar& b = f.get_bar();
std::cout << b << "\n";
}
>
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for
ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
>
"ComeauTest.c", line 21: error: no operator "<<" matches these
operands
operand types are: std::ostream << const foo<int>::bar
std::cout << b << "\n";
^
>
1 error detected in the compilation of "ComeauTest.c".
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Ares Lagae
Guest
 
Posts: n/a
#3: Oct 20 '08

re: stream operator of a class nested in a class template


On Oct 20, 4:05 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:

Thank you for your quick reply.
Quote:
Your argument is declared non-const here, but you pass a const ref.
I have added "const" but that did not change anything.
Quote:
Also, this is a non-deducible context.
So it seems. The call "operator<< <char, std::char_traits<char>,
int>(std::cout, b)" works.

Can you explain Why?

Best regards,

Ares
Victor Bazarov
Guest
 
Posts: n/a
#4: Oct 20 '08

re: stream operator of a class nested in a class template


Ares Lagae wrote:
Quote:
On Oct 20, 4:05 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
>
Thank you for your quick reply.
>
Quote:
>Your argument is declared non-const here, but you pass a const ref.
>
I have added "const" but that did not change anything.
>
Quote:
>Also, this is a non-deducible context.
>
So it seems. The call "operator<< <char, std::char_traits<char>,
int>(std::cout, b)" works.
>
Can you explain Why?
Explain why what? Why it's a non-deducible context? I don't know.
Here, the boilerplate answer is "because the Standard says so", but why
it's so in the Standard... There are *probably* cases in which the
compiler would have hard time deciding and the Standard Committee did
not want to impose the "undue hardship" on the compiler implementors.
But your guess is probably as good as mine. Try looking in the archives
for "non-deducible context".

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
James Kanze
Guest
 
Posts: n/a
#5: Oct 20 '08

re: stream operator of a class nested in a class template


On Oct 20, 4:44*pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
Quote:
Ares Lagae wrote:
Quote:
On Oct 20, 4:05 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
Quote:
Quote:
Thank you for your quick reply.
Quote:
Quote:
Quote:
Your argument is declared non-const here, but you pass a const ref.
Quote:
Quote:
I have added "const" but that did not change anything.
Quote:
Quote:
Quote:
Also, this is a non-deducible context.
Quote:
Quote:
So it seems. The call "operator<< <char, std::char_traits<char>,
int>(std::cout, b)" works.
Quote:
Quote:
Can you explain Why?
Quote:
Explain why what? *Why it's a non-deducible context? *I don't
know. Here, the boilerplate answer is "because the Standard
says so", but why it's so in the Standard... *There are
*probably* cases in which the compiler would have hard time
deciding and the Standard Committee did not want to impose the
"undue hardship" on the compiler implementors. But your guess
is probably as good as mine. *Try looking in the archives for
"non-deducible context".
I wasn't present during the discussions concerning this
particular point, but I can make some good guesses as to why it
isn't deducible. In the general case, the only way to deduce it
would be to try every possible instantiation, to see if one
matches---until you've instantiated Outer<T>, you can't know
what Outer<T>::Inner is. Given that the number of possible
instantiations is infinite, the committee probably felt that
this was asking a little too much of the implementors.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Closed Thread