473,403 Members | 2,366 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,403 software developers and data experts.

Serialisation of STL-container - fails with maps...

Hi,

a collegue of mine is trying to write a serialisable container (reads at
construction, writes at destruction).
The writing part is pretty easy: simply iterate through the container and
write into the file.
Reading from the file is (should) be easy too:
while you're getting data from the file (stream) insert it into your
container.
Unfortunatly this fails with the container map, because the
map::value_type's key is const :-/

This is the stripped code:

#include <list>
#include <vector>
#include <map>
#include <set>
#include <deque>

template< class containerT >
class MyContainer : public containerT
{
public:
void read()
{
typename containerT::value_type val;

/* normally:
read from file and make the assigment,
this is simply for demonstration
*/
val = val;

/* insert into container */
insert(end(), val);
}
};
template< class containerT >
void foo()
{
MyContainer< containerT > cont;
cont.read();
}

int main(int, char**)
{
/* compiles */
foo< std::vector< int > >();
foo< std::list< char > >();
foo< std::set< char > >();
foo< std::deque< long > >();

/* fails */
foo< std::map< char, int > >();
return 0;
}
Any ideas, how to modify the code for being able to assign to the value and
add to the container??

The read function would look something like this:

void read()
{
std::ifstream stream(m_path.c_str());
while (!stream.eof())
{
typename containerT::value_type val;
stream >> val;
insert(end(), val);
}
}

Thanks in advance :)
Jorge
Jul 19 '05 #1
7 2616
Jorge Schramm wrote:
Hi,

a collegue of mine is trying to write a serialisable container (reads
at construction, writes at destruction).
The writing part is pretty easy: simply iterate through the container
and write into the file.
Reading from the file is (should) be easy too:
while you're getting data from the file (stream) insert it into your
container.
Unfortunatly this fails with the container map, because the
map::value_type's key is const :-/ [SNIP] Any ideas, how to modify the code for being able to assign to the
value and add to the container??

[SNIP]

Try to find it. If found, erase it. Then insert. This is the way to do it
with map and set.

--
Attila aka WW
Jul 19 '05 #2
Hi Attila,

thanks for your answer.
Try to find it. If found, erase it. Then insert. This is the way to do
it with map and set.


Unfortunately this is not the problem :-/ The line with the assignment fails
compiling for std::map.

| typename containerT::value_type val;
| val = val; // fails
This is because the value_type of map is a pair, having its key *const*.
I'd like to know an alternative :)

Jorge
Jul 19 '05 #3
Jorge Schramm wrote:
Hi Attila,

thanks for your answer.
Try to find it. If found, erase it. Then insert. This is the way
to do it with map and set.


Unfortunately this is not the problem :-/ The line with the
assignment fails compiling for std::map.
typename containerT::value_type val;
val = val; // fails


This is because the value_type of map is a pair, having its key
*const*. I'd like to know an alternative :)


The right eay to do it (or alternative as you call it) is to search for the
key part. If you find it, delete it. Then insert the new.

PSEUDO CODE!

void read()
{
typedef typename containerT::value_type value_type;
typedef typename containerT::iterator iterator;
// read key and value
iterator it = this->find(key);
if (key != this->end()) {
this->erase(key);
}
this->insert(end(), make_pair(key,value));
}

BTW do *not* inherit from the conatiner! Have it as a member. By
inheriting from it you wonder to two-phase name lookup land and *all* the
names coming from the container has to be prefixed with typename or this->
to make sure it will work.

--
Attila aka WW
Jul 19 '05 #4
Attila Feher wrote:
BTW do *not* inherit from the conatiner! Have it as a member. By
inheriting from it you wonder to two-phase name lookup land and *all*
the names coming from the container has to be prefixed with typename
or this-> to make sure it will work.


Update. You will still need typename before the types if it is a member.
But since it is a member you will not run into trouble by leaving out the
this-> before the member function calls. If you do leave out (and the
compiler "starts" to support two phase name lookup) you can end up calling
the std::find instead of the members etc. In addition your container class
is not a map (if I understand it right), it is implemented in terms of a map
(or whatever container you use).

BTW I suggest you read Scott Meyers Effective STL and Item #2, Beware of the
illusion of container independent code.

--
Attila aka WW
Jul 19 '05 #5
On Tue, 07 Oct 2003 13:42:25 +0200, Jorge Schramm
<jo***********@web.de> wrote:
Hi,

a collegue of mine is trying to write a serialisable container (reads at
construction, writes at destruction).
The writing part is pretty easy: simply iterate through the container and
write into the file.
Reading from the file is (should) be easy too:
while you're getting data from the file (stream) insert it into your
container.
Unfortunatly this fails with the container map, because the
map::value_type's key is const :-/


Here's a version that works on MSVC7.1. It won't work on earlier
versions, since they don't support partial specialization, which is
required to solve this problem (there may be an MSVC6 solution - I'll
have a fiddle).

Container persistence systems have been done before. You might want to
check out progress of the boost serialization library (see the files
section of www.boost.org)

#include <list>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <fstream>

template <class T>
struct value_traits
{
typedef T value_type;
typedef T non_const_value_type;

static std::istream& get_from_stream(std::istream& is,
non_const_value_type& t)
{
is >> t;
return is;
}
};

template <class T, class U>
struct value_traits<std::pair<T const, U> >
{
typedef std::pair<T const, U> value_type;
typedef std::pair<T, U> non_const_value_type;
static std::istream& get_from_stream(std::istream& is,
non_const_value_type& t)
{
is >> t.first >> t.second;
return is;
}
};

template< class containerT >
class MyContainer : public containerT
{
public:
std::string m_path;

void read()
{
std::ifstream stream(m_path.c_str());
typedef value_traits<typename containerT::value_type> traits;
typename traits::non_const_value_type val;
while (traits::get_from_stream(stream, val))
{
this->insert(this->end(), val);
}
}
};
template< class containerT >
void foo()
{
MyContainer< containerT > cont;
cont.read();
}

int main(int, char**)
{
/* compiles */
foo< std::vector<int> >();
foo< std::list<char> >();
foo< std::set<char> >();
foo< std::deque<long> >();

/* fails */
foo< std::map<char, int> >();
return 0;
}
Jul 19 '05 #6
Hi tom_usenet,

thanks! Works on Linux with gcc 3.2.2 too ;)
Nice idea using partial specialisation!!

Jorge
Jul 19 '05 #7
tom_usenet wrote:
Here's a version that works on MSVC7.1. It won't work on earlier
versions, since they don't support partial specialization, which is
required to solve this problem (there may be an MSVC6 solution - I'll
have a fiddle).


*argh* my collegue uses msvc 6.0 :/

We made a workaround with a load-policy. It's not very nice but it works.

template< class containerT, typename loadPolicyT = defaultLoadPolicy >
class MyContainer : public containerT
{
void read()
{
std::ifstream stream(m_path.c_str());
loadPolicy::load(stream, *this);
}
}
Thx,
Jorge
Jul 19 '05 #8

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

Similar topics

2
by: unknow | last post by:
I want to do a serialisation in pure C++ but i don't know how. Do you have some useful links ? Thanks
1
by: Pierre Couderc | last post by:
I want to serialise quickly a "simple" vector : (simple is to say with basic types and no pointers) such as : class c { int i,j; double z; }
2
by: msnews.microsoft.com | last post by:
Hi Here is another EASY question When you serialise an object in .NET, serialisation adds defaut attributes that I dont care EXEMPLE : <root_test...
1
by: lobrys | last post by:
Hi everybody here is a question I have this class that a want to serialize : Public Class BOO <XmlAttributeAttribute()> Public THING As String <XmlElementAttribute("param")> Public p() As...
2
by: lobrys | last post by:
Hi everybody what are the objets for the folowing XML serialisation : (I have problem with "name" and "datatype") <vehicule type="car"> <name datatype="String">Megane</name> </inventory> ...
1
by: McGiv | last post by:
Hi, I'm trying to serialise some objects and I've can't get the built in serialisation to output exactly what I want. For the moment I'm implementing the IXmlSerializable interface and doing it...
1
by: BrentonMCA | last post by:
I want to be able to serialise an object and then pass the serialisation text as a string to a Web service without serialising to a file first. I also want to be able to deserialise from the text...
2
by: gary | last post by:
Hi, When I serialise a class to XML which has properties I sometimes have properties that are like this - public double SpeedMPH { get { return (double)Math.Round(windSpeed*2.23693629,2); }...
2
by: ashwinij | last post by:
Hello The steps which i am doing in my program 1) I am having an xml file. 2) I am performing some updations in the file using XQueryUtil class from nux package. 3)After that i am...
1
by: OrionLee | last post by:
I am using C# to work with a 3rd party DLL (Nevron Charts), and attempting to serialise it. The serialisation itself is handled somewhere inside the DLL, so to get it to happen you call the Nevron's...
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: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.