[boost::function] Getting base class pointer of functor ?
Hello there, Short version: Are there any reasons, why base class access is currently not allowed/implemented in boost::function (via target() function)? Long version/explanation/scenario: I have a class using boost::any which I use for data exchange between different modules of my program. Some modules are able to process the data if it contains "numbers" (in contrast to other arbitrary data structures), ie. basically POD. These modules do not necessarily bother what _exact_ type the provided number is (some do, some don't) and might just use it as, e.g. double, so they don't care what type was originally inserted into the boost::any as long as they get a double-converted value out of it. As boost::any only allows to get the original type out of it with any_cast<T>, the class provides a set of conversion functions like boost::function< int () > toInt; boost::function< short () > toShort; ... ... struct Converter_base { Converter_base( const boost::any* a ) : m_any(a) {}; public: const boost::any* m_any; }; template< typename Target, typename Source > struct Converter : public Converter_base{ Converter( const boost::any* a ) : Converter_base(a) {}; T operator()() const { return boost::numeric_cast<Target>( * boost::any_cast<Source>( Converter_base::m_any ) ); }; }; template< typename SourceType > void setValue ( SourceType& value ) { m_value = value // this is boost::any toInt = Converter< int, SourceType > ( &m_value ); toShort = Converter< short, SourceType > ( &m_value ); ...... } This allows me to ask for the value converted to my desired type and receiving an exception if the conversion is not possible (or produces overflows). The problem is that the functor Converter is not copy-constructible because of the pointer to boost::any. So I have to take care of setting the correct pointer in the copy constructor of my data exchange class. In order to get the pointer to the converter functor and thus to the mep_any, I need to know SourceType. But since the module that provides the data and the module that consumes the data don't know about each other, the consumer doesn't know SourceType and cannot compile the appropriate copy constructor. Since mep_any is independent from the template arguments, I moved it to a base class Converter_base and let Converter inherit from it. Now, I want to access the functor via toInt.target<Converter_base>() in order to access/update the mep_any. But target() returns 0 .... I checked function/function_base.hpp and found: // DPG TBD: Since we're only storing a pointer, it's // possible that the user could ask for a base class or // derived class. Is that okay? Are there any reasons, why base class access is currently not allowed/implemented? Sorry that the post got a bit long, but I hope at leas my intention got somehow clear... Johannes
AMDG Johannes Stallkamp wrote:
Hello there,
Short version: Are there any reasons, why base class access is currently not allowed/implemented in boost::function (via target() function)?
Short answer: It's not at all easy to implement.
Long version/explanation/scenario:
Long answer: Boost.Function stores a pointer, but it's a void pointer so it loses all type information. The type information is stored separately, using std::type_info. With this setup, there is no way to determine whether the type that you ask for is a base of the stored type. The only way to implement this is to create a class the inherits multiply from the stored type and a common base. This allows the use of dynamic_cast to cross cast. This unfortunately requires that it be possible to derive from the stored type, so built-ins become a special case. In addition, it makes the small buffer optimization difficult to implement seriously hurting performance even when this feature is not used. In Christ, Steven Watanabe
Hello, does anyone managed to compile Boost.MPI suing mingw 4.1.2 under windows XP using MPICH 2 ? I tried to follow the instructions in the doc but i got a large number of failure while running bjam. Any help appreciated.
On Apr 1, 2008, at 3:05 PM, Joel FALCOU wrote:
does anyone managed to compile Boost.MPI suing mingw 4.1.2 under windows XP using MPICH 2 ? I tried to follow the instructions in the doc but i got a large number of failure while running bjam.
I haven't tried that particular combination. Could you describe what you did and show the errors you got? - Doug
Doug Gregor a écrit :
I haven't tried that particular combination. Could you describe what you did and show the errors you got?
Well, pretty simple : even if the user-build.jam file is modified to seek for mpich library in C:\Program Files\...\MPICH2\lib, the PATH set to find the include and lib directory for MPICH2, bjam fail to compile any files and outputs tons of error caused by the fact that NO MPI header file are found. I'm not in front of this machine right now, but i can do a step by step procedure later tonight with descriptive results.
Steven Watanabe schrieb: [...]
Long answer:
Boost.Function stores a pointer, but it's a void pointer so it loses all type information. The type information is stored separately, using std::type_info. With this setup, there is no way to determine whether the type that you ask for is a base of the stored type. The only way to implement this is to create a class the inherits multiply from the stored type and a common base. This allows the use of dynamic_cast to cross cast. This unfortunately requires that it be possible to derive from the stored type, so built-ins become a special case. In addition, it makes the small buffer optimization difficult to implement seriously hurting performance even when this feature is not used.
Alright, I see. Thanks for your detailed explanation. I modified the approach so that I don't have to store (and therefore copy) the pointer to the boost::any any more. Probably not optimal either, but I have to see. For now, it works. Thanks Johannes
participants (5)
-
Doug Gregor
-
Joel FALCOU
-
Joel Falcou
-
Johannes Stallkamp
-
Steven Watanabe