boost::serialization and shared_ptr<>

March 29th, 2011 by hari No comments »

Faced a funny problem yesterday. I started changing the implementation of a class such that it uses shared_ptr<> wrapped dynamic object rather than obj*. Naturally, the right and sane thing to do to. However, the same class also needs to support serialization, implemented using the boost::serialization library. After all the dependent code were fixed for this change, I got a nasty error while compiling

c:\sdks\boost_1_45_0\boost\serialization\access.hpp(118) : error C2039: ’serialize’ : is not a member of ’std::tr1::shared_ptr<_Ty>’
with
[
_Ty=myclass
]
….

The …. is 475 lines long! Intimidating, to say the least.

Digging into serialization docs, it was evident that it supports shared_ptr<>. Research on the web also pointed to the same. I was puzzled. What could I be doing wrong? I was almost about to revert back to my non-shared_ptr<> implementation and then it hit me — shared_ptr<> is now part of STL as it’s been adopted as part of TR1 and I could be using std::shared_ptr<> instead of the one in the boost namespace. And boost::serialization implementation could only be supporting the boost version.

My intuition was right, I was indeed using the std::shared_ptr<> (actually I had declared it as std::tr1::shared_ptr<>, as VC places all TR1 extensions in a separate namespace). Redeclaring it to use boost::shared_ptr<> fixed the problem.

Moral of the story:

  • Never be intimidated by template error messages.
  • If you’re using esoteric boost libraries, stick to boost data types even if equivalent ones are available as part of the TR1 standardization

C++0x Final Draft Approved

March 29th, 2011 by hari No comments »

Seems like the wait is over. The seemingly-never-ending deliberations have been concluded by the standards committee approving the changes that lead to the adoption of the C++0x standard. Sutter has more on his blog here.

Building boost

March 18th, 2011 by hari No comments »

Building boost using bjam is straightforward, that is if you just want to generate the default libraries that are linked to the DLL versions of CRT. But how do you build the libraries linking them to the static version of CRT? This is mysteriously missing from the boost Getting Started guide.

Want to capture it here as my own ever diminishing brain cells are proving to be increasingly unreliable.

bjam link=static[,shared] runtime-link=static threading=multi[,single] toolset=msvc {debug|release} stage

I’m pretty sure I’ll be referring to this in the near future when building boost on a new system:)

Case Insensitive STL Strings

January 5th, 2011 by hari No comments »

All these years of using STL strings, I never knew that one could use the std::char_traits template template parameter of std::basic_string<> to generate a case insensitive implementation of STL string. The trick is to customize the char_traits<> template overriding its  eq, lt, compare & find static functions which are implemented to perform case-insensitive operations.

struct cichartraits : public std::char_traits<char> { static bool eq(const char& _Left, const char& _Right) { return ::toupper(_Left) == ::toupper(_Right); } static bool lt(const char& _Left, const char& _Right) { return ::toupper(_Left) < ::toupper(_Right); } static int compare(const char* _First1, const char* _First2, size_t _Count) { return (::_strnicmp(_First1, _First2, _Count)); } static const char* find(const char*_First, size_t _Count, const char& _Ch) { while (_Count-- > 0 && ::toupper(!*_First) != ::toupper(_Ch)) { _First++; } return _Count >= 0 ? _First : 0; } };
typedef std::basic_string<char, cichar_traits> cistring;
cistring is now a case insensitive string. Which means operation such as these are possible without any additional effort.

cistring s("AbCdEf");
s.compare("abcdef"); // will return 0!
// a table keyed with a case insensitive string!
std::map<cistring, Employee> emptable;

Until now I used to declare such containers using a custom less functor  passed as the template template parameter to the container classes.

Goes to show how you keep discovering new things in C++ even after many years of using it.