using STL Container across the Files

P

Pallav singh

Hi All ,

How can we use STL Contianer Across the Files

example
file1.cc
map<int,int> xyz;

file2.cc
extern map<int,int> xyz;

It gives Error.

Thanks
Pallav Singh
 
P

Pascal J. Bourguignon

Pallav singh said:
Hi All ,

How can we use STL Contianer Across the Files

example
file1.cc
map<int,int> xyz;

file2.cc
extern map<int,int> xyz;

It gives Error.

What is map?

You are missing some #include and some 'using namespace'...
 
J

James Kanze

How can we use STL Contianer Across the Files
example
file1.cc
map<int,int> xyz;
file2.cc
extern map<int,int> xyz;
It gives Error.

What error? With what compiler? With the compilers I use, I
have no problems with:

file1.cc:
#include <map>
std::map< int, int > xyz ;

file2.cc
#include <map>
extern std::map< int, int > xzy ;

A bit of precaution may be necessary because of order of
initialization issues, but otherwise, there's no problem.
 
P

Pallav singh

What error?  With what compiler?  With the compilers I use, I
have no problems with:

file1.cc:
    #include <map>
    std::map< int, int > xyz ;

file2.cc
    #include <map>
    extern std::map< int, int > xzy ;

A bit of precaution may be necessary because of order of
initialization issues, but otherwise, there's no problem.

--
James Kanze (GABI Software)             email:[email protected]
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

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++

map1.cc

#include <iostream>
#include <map>
#include <iterator>

using namespace std;

class A
{
public :
int x;
int y;

void display()const
{ cout<<" Value of x " << x << endl ;
cout<<" value of y " << y << endl ;}
};

struct compare
{
bool operator()(const A & s1, const A & s2) const
{ return ((s1.x== s2.x) && (s1.y == s2.y)); }
};

std::map<A,int,compare> object;

object.insert(pair<A,int>(A(1,2), 2));
object.insert(pair<A,int>(A(3,4), 2));


map2.cc

#include <iostream>
#include <map>
#include <iterator>

using namespace std;

extern map<A,int,compare> object;
map<A,int,compare>::iterator iter;

int main()
{
cout << "Map size: " << object.size() << endl;
for( iter = object.begin(); iter != object.end(); ++iter )
cout << (*iter).first << ": " << (*iter).second << endl;

return 0;
}

i am getting compilation error's
 
I

Ian Collins

Pallav said:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++

map1.cc

#include <iostream>
#include <map>
#include <iterator>

using namespace std;

class A
{
public :
int x;
int y;

void display()const
{ cout<<" Value of x " << x << endl ;
cout<<" value of y " << y << endl ;}
};

struct compare
{
bool operator()(const A & s1, const A & s2) const
{ return ((s1.x== s2.x) && (s1.y == s2.y)); }
};

std::map<A,int,compare> object;

object.insert(pair<A,int>(A(1,2), 2));
object.insert(pair<A,int>(A(3,4), 2));


map2.cc

#include <iostream>
#include <map>
#include <iterator>

using namespace std;

extern map<A,int,compare> object;

What's a compare?
i am getting compilation error's

I'm not surprised. Why don't you show them?
 
J

James Kanze

#include <iostream>
#include <map>
#include <iterator>
using namespace std;

class A
{
public :
int x;
int y;
void display()const
{ cout<<" Value of x " << x << endl ;
cout<<" value of y " << y << endl ;}
};
struct compare
{
bool operator()(const A & s1, const A & s2) const
{ return ((s1.x== s2.x) && (s1.y == s2.y)); }
};
std::map<A,int,compare> object;

This is illegal. It's undefined behavior, so it may not give
you an error, but compare is not a valid. To be valid, the
comparison function must "induce a strict weak ordering on the
values". In particular, for a comparison function comp, if we
define a function equiv( a, b ) as being ! comp( a, b ) && !
comp( b, a ), then equiv must define an equivalence
relationship; for example, equiv( a, b ) && equiv( b, c ) implies
equiv( a, c ).
object.insert(pair<A,int>(A(1,2), 2));
object.insert(pair<A,int>(A(3,4), 2));

#include <iostream>
#include <map>
#include <iterator>
using namespace std;
extern map<A,int,compare> object;

What's A and compare, here? I don't see any definition of them.
map<A,int,compare>::iterator iter;
 
P

Pallav singh

This is illegal. It's undefined behavior, so it may not give
you an error, but compare is not a valid. To be valid, the
comparison function must "induce a strict weak ordering on the
values". In particular, for a comparison function comp, if we
define a function equiv( a, b ) as being ! comp( a, b ) && !
comp( b, a ), then equiv must define an equivalence
relationship; for example, equiv( a, b ) && equiv( b, c ) implies
equiv( a, c ).


What's A and compare, here? I don't see any definition of them.



--
James Kanze (GABI Software) email:[email protected]
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

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Hi

i tried it ..........But i am getting redifnation of ostream operator

File1.cc
#include <map>
#include <iostream>
#include "File3.cc"
using namespace std;

std::map<A, int , cmp > tmp;

void func()
{
tmp.insert( pair<A , int >(A(1,1), 10) );
tmp.insert( pair<A , int >(A(2,2), 20) );
tmp.insert( pair<A , int >(A(3,3), 30) );
tmp.insert( pair<A , int >(A(4,4), 40) );
tmp.insert( pair<A , int >(A(5,5), 50) );
}


File2.cc
#include <map>
#include <iostream>
#include <iterator>
#include "File3.cc"
using namespace std;

extern std::map<A, int , cmp > tmp;
extern void func();

int main()
{
std::map< A , int ,cmp >::iterator iter;
func();

for(iter = tmp.begin(); iter != tmp.end();iter++)
{ std::cout<<(*iter).first <<" "<<(*iter).second << endl; }

return 0;
}


File3.cc
#include<iostream>
using namespace std;

class A
{
public :
int x;
int y;

A(int x1,int y1) // Constructor
{
x = x1;
y = y1;
}

int operator==(const A &rhs) const
{
if( this->x != rhs.x) return 0;
if( this->y != rhs.y) return 0;
return 1;
}

friend ostream & operator<<(ostream &, const A &);

};

ostream &operator<<(ostream &output, const A &aaa)
{
output << aaa.x << ' ' << aaa.y ;
return output;
}

struct cmp
{
bool operator()(const A & lhs, const A & rhs)
{
if(lhs.x < rhs.x ) return 1;
return 0;
}
};


i am getting redifnation of ostream operator
 
F

Francesco

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Hi

i tried it ..........But i am getting redifnation of ostream operator

File1.cc
#include <map>
#include <iostream>
#include "File3.cc"
using namespace std;

std::map<A, int , cmp > tmp;

void func()
{
tmp.insert( pair<A , int >(A(1,1), 10) );
tmp.insert( pair<A , int >(A(2,2), 20) );
tmp.insert( pair<A , int >(A(3,3), 30) );
tmp.insert( pair<A , int >(A(4,4), 40) );
tmp.insert( pair<A , int >(A(5,5), 50) );

}

File2.cc
#include <map>
#include <iostream>
#include <iterator>
#include "File3.cc"
using namespace std;

extern std::map<A, int , cmp > tmp;
extern void func();

int main()
{
std::map< A , int ,cmp >::iterator iter;
func();

for(iter = tmp.begin(); iter != tmp.end();iter++)
{ std::cout<<(*iter).first <<" "<<(*iter).second << endl; }

return 0;

}

File3.cc
#include<iostream>
using namespace std;

class A
{
public :
int x;
int y;

A(int x1,int y1) // Constructor
{
x = x1;
y = y1;
}

int operator==(const A &rhs) const
{
if( this->x != rhs.x) return 0;
if( this->y != rhs.y) return 0;
return 1;
}

friend ostream & operator<<(ostream &, const A &);

};

ostream &operator<<(ostream &output, const A &aaa)
{
output << aaa.x << ' ' << aaa.y ;
return output;

}

struct cmp
{
bool operator()(const A & lhs, const A & rhs)
{
if(lhs.x < rhs.x ) return 1;
return 0;
}

};

i am getting redifnation of ostream operator

You have to rename "File3.cc" into something like "myheader.h", you
should include it in File1.cc and File2.cc and finally you should not
pass it directly to g++ - if I got it all right on the fly, I didn't
deeply examine it.

Hope that helps,
Francesco
 
J

James Kanze

i tried it ..........But i am getting redifnation of ostream
operator

That's because you're defining it multiple times.
File1.cc
#include <map>
#include <iostream>
#include "File3.cc"

What's this? The compiler doesn't care, but by convention,
files with names ending in .cc or .cpp (or .C or .cxx) are
source files, not headers, and so shouldn't be included.
File2.cc
#include <map>
#include <iostream>
#include <iterator>
#include "File3.cc"

Same thing here.
#include<iostream>
using namespace std;
class A
{
public :
int x;
int y;

A(int x1,int y1) // Constructor
{
x = x1;
y = y1;
}

int operator==(const A &rhs) const

Note that operator== should normally return bool.
{
if( this->x != rhs.x) return 0;
if( this->y != rhs.y) return 0;
return 1;
}

friend ostream & operator<<(ostream &, const A &);
};

The above (except for the using namespace) is a class
definition, which belongs in a header file if it is to be used
in more than one source file. Something like:

file A.hh:

#include <iosfwd> // since you don't need all of iostream.

struct A
{
int x ;
int y ;

A( int initialX, int initialY ) ;
bool operator==( A const& other ) const ;
friend std::eek:stream& operator<<( std::eek:stream&, A const&) ;
} ;

You can put inline definitions in the header, but I'd recommend
against it for normal classes. (For templates, the issues are a
bit different.) I'd also define a member function isEqual,
and make the operator== (and operator!=) non-members. (More a
style issue than otherwise, except that I use a template base
class to generate them automatically, so that I'm guaranteed
never to have one without the other, and that both have the same
definition of equality.)

Also, there's no real point in making operator<< a friend, since
all of the data are public.
ostream &operator<<(ostream &output, const A &aaa)
{
output << aaa.x << ' ' << aaa.y ;
return output;
}

This is implementation. It belongs in a source file, along with
the other function implementations, e.g.:

file A.cc

#include "A.hh" // Always first, to ensure that it
// is independent.
#include <ostream>

A::A(
int initialX,
int initialY )
: x( initialX )
, y( initialY )
{
}

bool
A::eek:perator==(
A const& other ) const
{
return x == other.x && y == other.y ;
}

std::eek:stream&
operator<<(
std::eek:stream& dest,
A const& object )
{
dest << object.x << ' ' << object.y ;
return dest ;
}
struct cmp
{
bool operator()(const A & lhs, const A & rhs)
{
if(lhs.x < rhs.x ) return 1;
return 0;

Why not just:
return lhs.x < rhs. x ;
?

Again, a mixture of definition and implementation. In this
case, the function is inline, so it's permitted to put this in a
header; the class is simple enough that many programmers would
even prefer it in a header, but I'd generally still use two
files here.

What I would also ask myself is whether this should be part of
the definition of A or not. If so, I would seriousy consider
making it an operator< member, and letting the default arguments
for map do their job. If not, then I would probably put it in a
separate header with a typedef of the map (in which case, I
probably would implement the function inline, rather than create
a separate source file just for it).
 
V

Vladimir Jovic

James said:
That's because you're defining it multiple times.


What's this? The compiler doesn't care, but by convention,
files with names ending in .cc or .cpp (or .C or .cxx) are
source files, not headers, and so shouldn't be included.

Not true if it contains a template class implementation - assuming
export is not implemented in a compiler ;)
 
F

Francesco

You have to rename "File3.cc" into something like "myheader.h", you
should include it in File1.cc and File2.cc and finally you should not
pass it directly to g++ - if I got it all right on the fly, I didn't
deeply examine it.

Don't forget about the double header inclusion checks too.

Francesco
 
J

James Kanze

Not true if it contains a template class implementation -
assuming export is not implemented in a compiler ;)

By convention, files whose names end in .cc or .cpp are source
files, and should not be included. Templates or not. Some
people (myself included) do like to put template implementations
in separate files, and include these from the header file, but
those files do not have names that end in .cc or .cpp. (Like
the g++ libraries, I use .tcc.)
 
V

Vladimir Jovic

James said:
By convention, files whose names end in .cc or .cpp are source
files, and should not be included. Templates or not. Some
people (myself included) do like to put template implementations
in separate files, and include these from the header file, but
those files do not have names that end in .cc or .cpp. (Like
the g++ libraries, I use .tcc.)

Nice trick.

I remember having a different problem few years ago, because I included
a cpp file in few other cpp files. That cpp file had defined in the
anonymous namespace a template function with a static variable.
Unfortunately I forgot the details, but I had fun time finding this bug :(
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,999
Messages
2,570,243
Members
46,835
Latest member
lila30

Latest Threads

Top