Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

troubles overloading << in a templated class

33 views
Skip to first unread message

Popping mad

unread,
Nov 7, 2016, 1:52:46 AM11/7/16
to

I have a class that has a std::vetcor of a type of a templated class that
looks like this

template<class cost>
class Pstates
{
public:
Pstates (std::vector< state<cost> > x)
: _vstate{x}
{
for( const auto& y : _vstate)
std::cout << y << std::endl;
};

etc

I can get this to print.
the overload looks like this

friend std::ostream &std::operator<<( std::ostream &output, const
tree::state<cost> &p )
{
output << "nam => " << p.nam() << "\tcost=> " << p.r() << std::endl;
return output;
}


The error that I'm getting is:


|| g++ -Wall -ggdb -c nodes.cpp
|| g++ -Wall -ggdb -o fitch.o -c fitch.cpp
|| nodes.h: In instantiation of ‘tree::Pstates<cost>::Pstates
(std::vector<tree::state<cost> >) [with cost = int]’:
fitch.cpp|15 col 47| required from here
nodes.h|158 col 16| error: no match for ‘operator<<’ (operand types are
‘std::ostream {aka std::basic_ostream<char>}’ and ‘const
tree::state<int>’)
|| std::cout << y << std::endl;
|| ~~~~~~~~~~^~~~
/usr/include/c++/6.2.1/ostream|628 col 5| note: candidate:
std::basic_ostream<_CharT, _Traits>& std::operator<<
(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char;
_Traits = std::char_traits<char>; _Tp = tree::state<int>] <near match>
|| operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)


I thought that const tree::state<int> was a match

http://www.nylxs.com/docs/thesis/src/fitch/
and
http://www.nylxs.com/docs/thesis/src/fitch/nodes.h
are the full source. It is small yet.

Öö Tiib

unread,
Nov 7, 2016, 2:25:28 AM11/7/16
to
On Monday, 7 November 2016 08:52:46 UTC+2, Popping mad wrote:
> I have a class that has a std::vetcor of a type of a templated class that
> looks like this
>
> template<class cost>
> class Pstates
> {
> public:
> Pstates (std::vector< state<cost> > x)
> : _vstate{x}
> {
> for( const auto& y : _vstate)
> std::cout << y << std::endl;
> };
>
> etc
>
> I can get this to print.
> the overload looks like this
>
> friend std::ostream &std::operator<<( std::ostream &output, const
> tree::state<cost> &p )

You lost me right here.
Why operator is qualified as 'std::operator<<'? Do you want it to be
in namespace 'std'? Why that operator is friend of 'tree::Pstates<cost>'?

A name first declared in a friend declaration within class or class
template X becomes a member of the innermost enclosing namespace of X
[IOW 'tree'], but is not accessible for lookup (except argument-dependent lookup that considers X [IOW 'tree::Pstates<cost>' that is not among its arguments]) unless a matching declaration at the namespace scope is
provided [that is not] - see namespaces for details.

I put mine comments in []. So lookup can't find that operator of yours.

Popping mad

unread,
Nov 7, 2016, 6:21:52 AM11/7/16
to
On Sun, 06 Nov 2016 23:25:17 -0800, Öö Tiib wrote:

> On Monday, 7 November 2016 08:52:46 UTC+2, Popping mad wrote:
>> I have a class that has a std::vetcor of a type of a templated class
>> that looks like this
>>
>> template<class cost>
>> class Pstates {
>> public:
>> Pstates (std::vector< state<cost> > x)
>> : _vstate{x}
>> {
>> for( const auto& y : _vstate)
>> std::cout << y << std::endl;
>> };
>>
>> etc
>>
>> I can get this to print.
>> the overload looks like this
>>
>> friend std::ostream &std::operator<<( std::ostream &output, const
>> tree::state<cost> &p )
>
> You lost me right here.
> Why operator is qualified as 'std::operator<<'? Do you want it to be in
> namespace 'std'? Why that operator is friend of 'tree::Pstates<cost>'?
>

It is qualified as std because we are operating in the namespace of tree

http://stackoverflow.com/questions/236801/should-operator-be-implemented-
as-a-friend-or-as-a-member-function#237074


> A name first declared in a friend declaration within class or class
> template X becomes a member of the innermost enclosing namespace of X
> [IOW 'tree'], but is not accessible for lookup (except
> argument-dependent lookup that considers X [IOW 'tree::Pstates<cost>'

I don't know what this means. What is IOW?


> that is not among its arguments]) unless a matching declaration at the
> namespace scope is provided [that is not] - see namespaces for details.
>
> I put mine comments in []. So lookup can't find that operator of yours.

What?

Paavo Helde

unread,
Nov 7, 2016, 7:40:27 AM11/7/16
to
On 7.11.2016 13:21, Popping mad wrote:
> On Sun, 06 Nov 2016 23:25:17 -0800, Öö Tiib wrote:
>
>> A name first declared in a friend declaration within class or class
>> template X becomes a member of the innermost enclosing namespace of X
>> [IOW 'tree'], but is not accessible for lookup (except
>> argument-dependent lookup that considers X [IOW 'tree::Pstates<cost>'
>
> I don't know what this means. What is IOW?

http://lmgtfy.com/?iie=1&q=what+is+IOW%3F


Öö Tiib

unread,
Nov 7, 2016, 3:36:07 PM11/7/16
to
On Monday, 7 November 2016 13:21:52 UTC+2, Popping mad wrote:
> On Sun, 06 Nov 2016 23:25:17 -0800, Öö Tiib wrote:
>
> > On Monday, 7 November 2016 08:52:46 UTC+2, Popping mad wrote:
> >> I have a class that has a std::vetcor of a type of a templated class
> >> that looks like this
> >>
> >> template<class cost>
> >> class Pstates {
> >> public:
> >> Pstates (std::vector< state<cost> > x)
> >> : _vstate{x}
> >> {
> >> for( const auto& y : _vstate)
> >> std::cout << y << std::endl;
> >> };
> >>
> >> etc
> >>
> >> I can get this to print.
> >> the overload looks like this
> >>
> >> friend std::ostream &std::operator<<( std::ostream &output, const
> >> tree::state<cost> &p )
> >
> > You lost me right here.
> > Why operator is qualified as 'std::operator<<'? Do you want it to be in
> > namespace 'std'? Why that operator is friend of 'tree::Pstates<cost>'?
> >
>
> It is qualified as std because we are operating in the namespace of tree

Yes but AFAIK we can't have friend functions from different namespaces.
So if you resolve the defect diagnosed you will be likely diagnosed for
qualifying friend function with that 'std'.

>
> http://stackoverflow.com/questions/236801/should-operator-be-implemented-
> as-a-friend-or-as-a-member-function#237074

That stack overflow question has seemingly no relevance to your issue nor
to mine questions.

The operator of yours above does not operate on 'tree::Pstates<cost>'
(but does on 'std::ostream' and 'tree::state<cost>' whose friend it is
not) so *again* why it is friend of 'tree::Pstates<cost>'?


> What?

C++ does work in a certain way; I attempted to explain to you how.



Popping mad

unread,
Nov 7, 2016, 9:58:32 PM11/7/16
to
On Sun, 06 Nov 2016 23:25:17 -0800, Öö Tiib wrote:


>> friend std::ostream &std::operator<<( std::ostream &output, const
>> tree::state<cost> &p )
>
> You lost me right here.
> Why operator is qualified as 'std::operator<<'? Do you want it to be in
> namespace 'std'? Why that operator is friend of 'tree::Pstates<cost>'?

I'm a bit perplexed as to why this is causing confusion since overloaded
stream operators are always nonmembers. This is a common problem.



Stream extraction and insertion

The overloads of operator>> and operator<< that take a std::istream& or
std::ostream& as the left hand argument are known as insertion and
extraction operators. Since they take the user-defined type as the right
argument (b in a@b), they must be implemented as non-members.

std::ostream& operator<<(std::ostream& os, const T& obj)
{
// write obj to stream
return os;
}
std::istream& operator>>(std::istream& is, T& obj)
{
// read obj from stream
if( /* T could not be constructed */ )
is.setstate(std::ios::failbit);
return is;
}

These operators are sometimes implemented as friend functions.

http://en.cppreference.com/w/cpp/language/operators

I don't want it to be in the std namespace, it IS in the std namespace.
Where am I confused here?

Popping mad

unread,
Nov 7, 2016, 10:00:33 PM11/7/16
to
On Mon, 07 Nov 2016 12:35:37 -0800, Öö Tiib wrote:


> Yes but AFAIK we can't have friend functions from different namespaces.

is that a fact? I'm ignorant.

Alf P. Steinbach

unread,
Nov 7, 2016, 10:14:37 PM11/7/16
to
The examples you show above are not in the `std` namespace.


> Where am I confused here?

Not sure.

The problem is that you're qualifying the operator, as `std::operator>>`.


Cheers & hth.,

- Alf

Paavo Helde

unread,
Nov 8, 2016, 10:16:47 AM11/8/16
to
Any function what you write will be in the namespace you put it in. For
example:

namespace Bwlchgwyn {
std::ostream& operator<<(std::ostream& os, const T& obj) {/*...*/}
}

This operator<< is in a namespace Bwlchgwyn. It's as simple as that.


> Where am I confused here?

Maybe you are confused by the fact that the function return type is
defined in the std namespace? Or maybe you are confused because
sometimes one needs to write specializations for templates defined in
the std namespace. Who knows!






0 new messages