$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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)