why is operator<< not found | | |
I've tried the below code with MSVC and Comeau online compiler.
Both complain that operator<< for Outer<part<size_t> >::inner is not defined.
So how do I declare it without doing full specialization?
I've tried a template on any type, like Outer<AnyT>::inner (see below)
Also tried a template on the templated type: Outer<part<X> >::inner // (see below)
I can't find a typo? What is the rule in operation here?
Thanks,
homsan
---------------- 8< -----------------
#include <iostream>
template<class SizeT>
struct part {
typedef SizeT size_type;
size_type size;
};
template<class PartT>
class Outer
{
public:
typedef PartT part_type;
struct inner {
part_type p;
};
inner get() const { return inner(); }
};
// WHY is this not found in main()?
template<class PartT>
inline std::ostream& operator<<(std::ostream& ostr, typename Outer<PartT>::inner const& it)
{
ostr << it.p.size << " by Jove\n";
return ostr;
}
// Nor is this found - what gives?
template<class SizeT>
inline std::ostream& operator<<(std::ostream& ostr, typename Outer<part<SizeT> >::inner const& it)
{
ostr << it.p.size << " by Jove\n";
return ostr;
}
// Now this works, but of course I don't want to redefine for every specialization...
/*
std::ostream& operator<<(std::ostream& ostr, Outer<part<size_t> >::inner const& it)
{
ostr << it.p.size << " by Jove\n";
return ostr;
}
*/
int main() {
Outer<part<size_t> > yippie;
std::cout << yippie.get();
return 0;
} | | | | re: why is operator<< not found
homsan toft wrote:[color=blue]
> I've tried the below code with MSVC and Comeau online compiler.
> Both complain that operator<< for Outer<part<size_t> >::inner is not
> defined. So how do I declare it without doing full specialization?
>
> I've tried a template on any type, like Outer<AnyT>::inner (see
> below) Also tried a template on the templated type: Outer<part<X>[color=green]
> >::inner[/color]
> // (see below) I can't find a typo? What is the rule in operation here?
>
> Thanks,
> homsan
> ---------------- 8< -----------------
>
> #include <iostream>
>
> template<class SizeT>
> struct part {
> typedef SizeT size_type;
> size_type size;
> };
>
> template<class PartT>
> class Outer
> {
> public:
> typedef PartT part_type;
> struct inner {
> part_type p;
> };
> inner get() const { return inner(); }
> };
>
> // WHY is this not found in main()?[/color]
This is "non-deducible context". You're not using 'PartT' here.
Why do you think you need it? Why couldn't you use
template<class Blah> ..., Blah const& it)
???
[color=blue]
> template<class PartT>
> inline std::ostream& operator<<(std::ostream& ostr, typename
> Outer<PartT>::inner const& it) {
> ostr << it.p.size << " by Jove\n";
> return ostr;
> }
>
> // Nor is this found - what gives?[/color]
It's called "non-deducible context". Why do you need to know 'SizeT'
anyway?
You're not using it. Why could't you simply use OuterInner?
[color=blue]
> template<class SizeT>
> inline std::ostream& operator<<(std::ostream& ostr, typename
> Outer<part<SizeT> >::inner const& it) {
> ostr << it.p.size << " by Jove\n";
> return ostr;
> }
>
> // Now this works, but of course I don't want to redefine for every
> specialization... /*
> std::ostream& operator<<(std::ostream& ostr, Outer<part<size_t>[color=green]
> >::inner const& it) {[/color]
> ostr << it.p.size << " by Jove\n";
> return ostr;
> }
> */
>
> int main() {
> Outer<part<size_t> > yippie;
> std::cout << yippie.get();
> return 0;
> }[/color]
--
Please remove capital As from my address when replying by mail | | | | re: why is operator<< not found
Victor Bazarov wrote:
[color=blue][color=green]
>>
>>template<class PartT>
>>class Outer
>>{
>>public:
>>typedef PartT part_type;
>>struct inner {
>>part_type p;
>>};
>>inner get() const { return inner(); }
>>};
>>
>>// WHY is this not found in main()?
>>template<class PartT>
>>inline std::ostream& operator<<(std::ostream& ostr, typename Outer<PartT>::inner const& it) {[/color]
>
> This is "non-deducible context". You're not using 'PartT' here.
> Why do you think you need it? Why couldn't you use
>
> template<class Blah> ..., Blah const& it)
>
> ???[/color]
Ah, so I can't specialize or overload on a nested type (the Standard forbids).
Thanks Victor, found out now by search on the phrase you provided.
[color=blue][color=green]
>>template<class SizeT>
>>inline std::ostream& operator<<(std::ostream& ostr, typename Outer<part<SizeT> >::inner const& it) {[/color]
>
> It's called "non-deducible context". Why do you need to know 'SizeT' anyway?
> You're not using it. Why could't you simply use OuterInner?[/color]
And so you mean a *non-nested type* OuterInner.
Ok, either that or define a method print(ostream&) on Outer<T>::inner,
and/or require specializing operator<< for every Outer<T> there may be.
Of course my real code uses several representations of part<SizeT> with 16/32/64-bit
size types, and both Outer and inner use the part_type all over.
I thought it nice to make the /part_type/ of struct inner explicitly dependent on its
Outer owner (Outer is a container of inner's), but as you say it brings other problems.
So will reconsider my (ahem) design.
Thanks,
homsan | | | | re: why is operator<< not found
"homsan toft" <nowhere@specific.org> skrev i meddelandet
news:e5k5nf$6sq$1@oden.abc.se...[color=blue]
> Victor Bazarov wrote:
>[color=green]
>> It's called "non-deducible context". Why do you need to know
>> 'SizeT' anyway?
>> You're not using it. Why could't you simply use OuterInner?[/color]
>
> And so you mean a *non-nested type* OuterInner.
> Ok, either that or define a method print(ostream&) on
> Outer<T>::inner,
> and/or require specializing operator<< for every Outer<T> there may
> be.[/color]
No, if you want to output the 'inner' type, you should specialize
operator<< for 'inner' !
Outer<T> has nothing to do with the operator, if it is 'inner' you
want it to operate on.
[color=blue]
>
> Of course my real code uses several representations of part<SizeT>
> with 16/32/64-bit
> size types, and both Outer and inner use the part_type all over.[/color]
And those size types already have operator<< defined for them, right?
Bo Persson | | | | re: why is operator<< not found
Bo Persson wrote:[color=blue]
> "homsan toft" <nowhere@specific.org> skrev i meddelandet
> news:e5k5nf$6sq$1@oden.abc.se...[color=green]
> > Victor Bazarov wrote:
> >[color=darkred]
> >> It's called "non-deducible context". Why do you need to know
> >> 'SizeT' anyway?
> >> You're not using it. Why could't you simply use OuterInner?[/color]
> >
> > And so you mean a *non-nested type* OuterInner.
> > Ok, either that or define a method print(ostream&) on
> > Outer<T>::inner,
> > and/or require specializing operator<< for every Outer<T> there may
> > be.[/color]
>
> No, if you want to output the 'inner' type, you should specialize
> operator<< for 'inner' !
>
> Outer<T> has nothing to do with the operator, if it is 'inner' you
> want it to operate on.
>[color=green]
> >
> > Of course my real code uses several representations of part<SizeT>
> > with 16/32/64-bit
> > size types, and both Outer and inner use the part_type all over.[/color]
>
> And those size types already have operator<< defined for them, right?[/color]
The "trick" workaround is to put it in its own namespace and make it
generic for that namespace. The outer class is specialised if that has
its own output. You can only do that for one nested class within an
outer class.
And if you're going to define a namespace anyway, just make the class
non-nested. You can then typedef it into your outer class if you want
to use it in templates. (ie outerClass<T>::inner would be typedef'ed). |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,467 network members.
|