473,387 Members | 1,542 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Problem with defining operator<< for std::ostream_iterator

I cannot compile the code which defines a std::map type consisting of
built in types and operator<< overload for std::map::value_type.
See the code below - I attach a full example.

Note: if I define map type with my new type (structure) everything is
OK. All compileres I've cheked report an error so I think it is a
problem with my code.

#include <algorithm>
#include <cstddef>
#include <fstream>
#include <iterator>
#include <map>

class A
{
struct S // behavior similar to built-in int
{
int i;
S( int _i ) : i( _i ) {}
};

typedef std::map< int, int Map1;
typedef std::map< int, S Map2;

// the function below cannot be found by
std::ostream_iterator< Map1::value_type >
friend std::ostream &operator<<( std::ostream &_ostr, const
Map1::value_type &_value )
{
return _ostr << _value.first << ' ' << _value.second;
}

friend std::ostream &operator<<( std::ostream &_ostr, const
Map2::value_type &_value )
{
return _ostr << _value.first << ' ' << _value.second.i;
}

Map1 m_map1;
Map2 m_map2;

public:
A(
const int *_keyStart,
const int *_valueStart,
const std::size_t _size
)
{
for ( std::size_t i = 0; i < _size; i++ )
{
m_map1.insert( Map1::value_type( _keyStart[i], _valueStart[i] ) );
m_map2.insert( Map2::value_type( _keyStart[i],
S( _valueStart[i] ) ) );
}
}

~A()
{
std::ofstream out( "test" );

out << "#### Map1 ####" << std::endl;
// this call does not compile
std::copy(
m_map1.begin(),
m_map1.end(),
std::ostream_iterator< Map1::value_type >( out, "\n" )
);

out << "\n#### Map2 ####" << std::endl;
std::copy(
m_map2.begin(),
m_map2.end(),
std::ostream_iterator< Map2::value_type >( out, "\n" )
);
}
};

int main()
{
int tab1[] = { 1, 3, 5, 2, 0 };
int tab2[ sizeof tab1 / sizeof *tab1 ] = { 1, 2, 3, 4, 5 };

A a( tab1, tab2, sizeof tab1 / sizeof *tab1 );
}

May 30 '07 #1
5 3628
On 30 Maj, 09:03, krzysztof.kono...@gmail.com wrote:
I cannot compile the code which defines a std::map type consisting of
built in types and operator<< overload for std::map::value_type.
See the code below - I attach a full example.

Note: if I define map type with my new type (structure) everything is
OK. All compileres I've cheked report an error so I think it is a
problem with my code.

#include <algorithm>
#include <cstddef>
#include <fstream>
#include <iterator>
#include <map>

class A
{
struct S // behavior similar to built-in int
{
int i;
S( int _i ) : i( _i ) {}
};

typedef std::map< int, int Map1;
typedef std::map< int, S Map2;

// the function below cannot be found by
// std::ostream_iterator< Map1::value_type >
friend std::ostream &operator<<(
std::ostream &_ostr,
const Map1::value_type &_value
)
{
return _ostr << _value.first << ' ' << _value.second;
}
The type of Map1::value_type is int which means that you are trying to
overload the operator
std::ostream &operator<<(std::ostream&, int)
To overload an operator at least one of the operands needs to be of
user-defined type (which is why it works with the second one).

--
Erik Wikström

May 30 '07 #2

Erik Wikström napisa³(a):
>
The type of Map1::value_type is int which means that you are trying to
overload the operator
std::ostream &operator<<(std::ostream&, int)
To overload an operator at least one of the operands needs to be of
user-defined type (which is why it works with the second one).

--
Erik Wikström
No, 'Map1::value_type' is of type 'std::pair< const int, int >', not
'int', so I am trying to define function:
std::ostream &operator<<( std::ostream&, const std::pair< const int,
int & )

If your statement would be true I got compilation error that
std::ostream &operator<<(std::ostream&, int) is already defined but I
didn't. My problem is that std::ostream_iterator< Map1::value_type >
cannot find my definition of operator<<().

If I write the code below everything is OK (it can find my definition
of operator<<() )
for ( Map1::const_iterator it = m_map1.begin(); it != m_map1.end(); it+
+ )
logfile << *it << std::endl;

May 30 '07 #3
kr***************@gmail.com wrote :
I cannot compile the code which defines a std::map type consisting of
built in types and operator<< overload for std::map::value_type.
See the code below - I attach a full example.

Note: if I define map type with my new type (structure) everything is
OK. All compileres I've cheked report an error so I think it is a
problem with my code.

[.. snip ..]

class A
{
struct S // behavior similar to built-in int
{
int i;
S( int _i ) : i( _i ) {}
};

typedef std::map< int, int Map1;
typedef std::map< int, S Map2;

friend std::ostream &operator<<( std::ostream &_ostr, const
Map1::value_type &_value )
{
return _ostr << _value.first << ' ' << _value.second;
}
Try not to define the operator<<() inside A. While the definition of
operator<<() injects that function in the enclosing namespace, it is
still in the lexical scope of the class itself, and it will therefore
not be found during overload resolution. The reason that it works when
you use 'A' or 'S' as template arguments for the map, your class *is*
searched because of ADL, and the correct operator<<() is found.

- Sylvester
May 30 '07 #4

Sylvester Hesp napisa (a):
Try not to define the operator<<() inside A. While the definition of
operator<<() injects that function in the enclosing namespace, it is
still in the lexical scope of the class itself, and it will therefore
not be found during overload resolution. The reason that it works when
you use 'A' or 'S' as template arguments for the map, your class *is*
searched because of ADL, and the correct operator<<() is found.

- Sylvester
Yes, I thought that ADL is reason in this case but I want to keep Map1
typedef private in class A so it implies operator<<() to be a friend
of class A.
Moreover, I need to declare operator<<() in std namespace.

Of course, there are work-arounds:
- use loop instead of std::copy and std::ostream_iterator
- make Map1 typedef public and define operator<<() in std namespace

I prefer first solution but it fits only the simple example I
provided. The main problem is still unresolved so I think I need to
dig in and understand ADL deeper and find a solution.

Thanks

May 30 '07 #5
kr***************@gmail.com wrote :
Sylvester Hesp napisa (a):
>Try not to define the operator<<() inside A. While the definition of
operator<<() injects that function in the enclosing namespace, it is
still in the lexical scope of the class itself, and it will therefore
not be found during overload resolution. The reason that it works when
you use 'A' or 'S' as template arguments for the map, your class *is*
searched because of ADL, and the correct operator<<() is found.

- Sylvester

Yes, I thought that ADL is reason in this case but I want to keep Map1
typedef private in class A so it implies operator<<() to be a friend
of class A.
Moreover, I need to declare operator<<() in std namespace.
Yes indeed, I didn't even think of that.
>
Of course, there are work-arounds:
- use loop instead of std::copy and std::ostream_iterator
- make Map1 typedef public and define operator<<() in std namespace
And obviously:
- Use a user defined type that behaves like another (built-in) type,
like your 'A::S'.

I think I personally prefer that solution - you don't have to put
anything into the std namespace and you don't impose certain standard
unspecified behaviour with the standard types. What if another
programmer in your project tries to do something similar to what you're
doing? That is impossible because you have already put a definition for
operator<<(std::map<int,int>) in the std namespace.

By using a custom type you keep things private to your class.

- Sylvester
May 30 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Ivan Paganini | last post by:
Hello all. I'm trying to use a vector<double> to alocate de data that i need, and I am passing by reference to the function to receive the values. The code goes like this: //code void...
6
by: gg | last post by:
If I have the following class - template <class T> class X { public: void dump(ostream & os) { // dump obj_ to os } private: T obj_; };
5
by: Kenneth | last post by:
<list> seems to be a powerful structure to store the related nodes in memory for fast operations, but the examples I found are all related to primitive type storage. I'm doing a project on C++...
29
by: aarthi28 | last post by:
Hi, I have written this code, and at the end, I am trying to write a vector of strings into a text file. However, my program is nor compiling, and it gives me the following error when I try to...
10
by: ozizus | last post by:
I overloaded operator << for STL map successfully: template <typename T1, typename T2ostream & operator << (ostream & o, map <T1,T2& m) { //code } the code works like a charm. Now, I want...
6
by: arnuld | last post by:
This works fine, I welcome any views/advices/coding-practices :) /* C++ Primer - 4/e * * Exercise 8.9 * STATEMENT: * write a program to store each line from a file into a *...
2
by: subramanian100in | last post by:
Consider the following piece of code: #include <iostream> #include <fstream> #include <vector> #include <string> #include <utility> #include <iterator> #include <algorithm> int main()
42
by: barcaroller | last post by:
In the boost::program_options tutorial, the author included the following code: cout << "Input files are: " << vm.as< vector<string() << "\n"; Basically, he is trying to print a vector...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.