Boost logo

Boost Users :

From: Pau Garcia i Quiles (pgquiles_at_[hidden])
Date: 2008-04-13 21:44:50


Hello,

I'm having trouble when adding elements to a ptr_map. If I use a
ptr_vector instead, it works (code for ptr_map and ptr_vector follows).

* With ptr_map:
===============

#include <iostream>
#include <string>
#include <boost/function.hpp>
#include <boost/any.hpp>
#include <boost/ptr_container/ptr_map.hpp>

class Base { };

class X : public Base {
   public:
     std::string text() { std::cout<< std::string("hello world!") <<
std::endl; return std::string("hello world!"); }
};

class Y : public Base {
   public:
     int value() { return 5; }
};

class Z : public Base {
   public:
     bool isEnabled() { return true; }
};

// [...]
// There will be hundreds of classes like X, Y and Z, only quite more complex

class ProxyBase {
   public:
     virtual boost::any field() = 0;
};

template<class T>
class Proxy : public ProxyBase {
   typedef T result_type;

   public:
     Proxy(T& inst, boost::function<boost::any ( T )> f) :
inst_(inst), f_(f) { ; };

     boost::any field() {
         return boost::any( f_(inst_) );
     }

     T& inst_;
   boost::function<boost::any ( T )> f_;

};

int main() {

   boost::ptr_map<std::string, ProxyBase> m;

   X x;
   Proxy<X>* px = new Proxy<X>(x, boost::mem_fn(&X::text));
   std::cout << "Calling a proxy object Proxy<X> outputs: " <<
boost::any_cast<std::string>( px->field() ) << std::endl;

// m.insert(std::string("test"), px ); // FIXME Why does this 'insert' fail?
// std::cout << "PTR_MAP Calling a proxy object Proxy<X> outputs: "
<< boost::any_cast<std::string>( m["test"].field() ) << std::endl;

   Y y;
   Proxy<Y>* py = new Proxy<Y>(y, boost::mem_fn(&Y::value));
   std::cout << "Calling a proxy object Proxy<Y> outputs: " <<
boost::any_cast<int>( py->field() )<< std::endl;

// m.insert(std::string("test2"), py); // FIXME Why does this 'insert' fail?
// std::cout << "PTR_VECTOR Calling a proxy object Proxy<Y> outputs:
" << boost::any_cast<int>( m["test2"].field() ) << std::endl;

   Z z;
   Proxy<Z>* pz = new Proxy<Z>(z, boost::mem_fn(&Z::isEnabled));
   std::cout << "Calling a proxy object Proxy<Z> outputs: " <<
boost::any_cast<bool>( pz->field() )<< std::endl;

// m.insert(std::string("test3"), pz); // FIXME Why does this 'insert' fail?
// std::cout << "PTR_VECTOR Calling a proxy object Proxy<Z> outputs:
" << boost::any_cast<bool>( m["test3"].field() ) << std::endl;

   return 0;
}

* With ptr_vector:
==================

#include <iostream>
#include <string>
#include <boost/function.hpp>
#include <boost/any.hpp>
#include <boost/ptr_container/ptr_vector.hpp>

class Base { };

class X : public Base {
   public:
     std::string text() { std::cout<< std::string("hello world!") <<
std::endl; return std::string("hello world!"); }
};

class Y : public Base {
   public:
     int value() { return 5; }
};

class Z : public Base {
   public:
     bool isEnabled() { return true; }
};

// [...]
// There will be hundreds of classes like X, Y and Z, only quite more complex

class ProxyBase {
   public:
     virtual boost::any field( std::string name ) = 0;
};

template<class T>
class Proxy : public ProxyBase {
   typedef T result_type;

   public:
     Proxy(std::string name, T& inst, boost::function<boost::any ( T
)> f) : name_(name), inst_(inst), f_(f) { ; };

     boost::any field( std::string name ) {
       if( name == name_ ) { // Just a stub to simulate a container lookup
         return boost::any( f_(inst_) );
       }
     }

   std::string name_;
     T& inst_;
   boost::function<boost::any ( T )> f_;

};

int main() {

   boost::ptr_vector<ProxyBase> vec;

   X x;
   Proxy<X>* px = new Proxy<X>("test", x, boost::mem_fn(&X::text));
   vec.push_back(px);
   std::cout << "Calling a proxy object Proxy<X> outputs: " <<
boost::any_cast<std::string>( px->field("test") ) << std::endl;
   std::cout << "PTR_VECTOR Calling a proxy object Proxy<X> outputs: "
<< boost::any_cast<std::string>( vec[0].field("test") ) << std::endl;

   Y y;
   Proxy<Y>* py = new Proxy<Y>("test2", y, boost::mem_fn(&Y::value));
   vec.push_back(py);
   std::cout << "Calling a proxy object Proxy<Y> outputs: " <<
boost::any_cast<int>( py->field( "test2" ) )<< std::endl;
   std::cout << "PTR_VECTOR Calling a proxy object Proxy<Y> outputs: "
<< boost::any_cast<int>( vec[1].field("test2") ) << std::endl;

   Z z;
   Proxy<Z>* pz = new Proxy<Z>("test3", z, boost::mem_fn(&Z::isEnabled));
   vec.push_back(pz);
   std::cout << "Calling a proxy object Proxy<Z> outputs: " <<
boost::any_cast<bool>( pz->field( "test3" ) )<< std::endl;
   std::cout << "PTR_VECTOR Calling a proxy object Proxy<Z> outputs: "
<< boost::any_cast<bool>( vec[2].field("test3") ) << std::endl;

   return 0;
}

-- 
Pau Garcia i Quiles
http://www.elpauer.org
(Due to my workload, I may need 10 days to answer)

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net