Hi !
I was using boost:function for a while now with success on
Visual C 7.0 ( MSVC 1300 ) .
I was always using the most actual boost 1.30.0 version from the CVS.
Today i updated the CVS again ( after two days of not doing so )
and suddenly my code which relied on boost::function does not compile
anymore.
I think there have some changes been made, so i need to change my code,
but since there is no boost::function
documentation in the CVS yet can someone please enlighten me what has
changed .. ?
Here is the relevant code:
( I have marked the line where compilation fails and provided the exact
error details below )
( This code compiled perfectly two days ago )
Header:
#include
#include
#include
#include "..\Platform\Config.h"
#include "IType.h"
namespace Fr
{
namespace Core
{
namespace Reflection
{
/// Function type for conversions.
/// Converts value from and stores the result in the target.
typedef boost::function1< boost::any,boost::any >
ConversionFunction;
FR_CORE_API void RegisterConversion(
ConversionFunction,const IType &,const IType & );
FR_CORE_API ConversionFunction * FindConversion( const
IType &,const IType & );
FR_CORE_API boost::any Convert( const
boost::any &,const IType & );
FR_CORE_API boost::any Convert( const
boost::any &,const boost::any &);
}
}
}
IMplementation:
/ Disable performance warning
#include "..\Platform\Config.h"
#include <vector>
#include
#include "IConverter.h"
#include "..\Debug\Exception.h"
using namespace Fr::Core::Reflection;
struct ConversionInfo
{
ConversionFunction function;
const IType * from;
const IType * to;
};
std::vector< ConversionInfo > sConversions;
void Fr::Core::Reflection::RegisterConversion( ConversionFunction
func,const IType & from,const IType & to )
{
for ( unsigned i = 0; i < sConversions.size(); i++ )
{
if ( *sConversions[i].to == to && *sConversions[i].from == from )
return;
}
// Else add
ConversionInfo info;
info.function = func;
info.from = &from;
info.to = &to;
// Store
sConversions.push_back( info );
}
ConversionFunction * Fr::Core::Reflection::FindConversion( const IType
&from,const IType &to )
{
// No conversion same type.
if ( from == to )
return NULL;
for ( unsigned int i = 0; i < sConversions.size(); i++ )
{
// Check
if ( *sConversions[i].from == from && *sConversions[i].to == to )
return &sConversions[i].function;
}
return NULL;
}
boost::any Fr::Core::Reflection::Convert( const boost::any &from,const
IType & to )
{
// First we try to get the type from the input data.
const IType & fromType = GetType(
ConvertCppTypename(from.type().name()) );
// Check if it worked
if ( fromType != NullType() )
{
if ( fromType == to )
return from;
// Try to find conversion.
ConversionFunction * func = FindConversion( fromType,to );
// If we have one
if ( func )
{
ConversionFunction convFunc = *func;
return convFunc( from );
}
else
{
std::string msg = "Unable to find conversion from: ";
msg += fromType.GetName();
msg += " to: ";
msg += to.GetName();
Throw(msg);
}
}
else
{
std::string msg = "Unable to retrieve type descriptor for data
type: ";
msg += from.type().name();
Throw( msg );
}
return from;
}
boost::any Fr::Core::Reflection::Convert( const boost::any &from,const
boost::any & to )
{
// First we try to get the type from the input data.
const IType & fromType = GetType(
ConvertCppTypename(from.type().name()) );
const IType & toType = GetType(
ConvertCppTypename(to.type().name()) );
// Check if it worked
if ( fromType != NullType() && toType != NullType() )
{
if ( fromType == toType )
return from;
if ( FindConversion( fromType,toType ) )
{
return Convert( from,toType );
}
return to;
}
else
{
return to;
}
return to;
}
//
-----------------------------------------------------------------------------
// Standard conversions
//
-----------------------------------------------------------------------------
static boost::any StringToFloat( const boost::any & input )
{
std::string data = boost::any_caststd::string ( input );
return boost::lexical_cast<float>(data);
}
static boost::any FloatToString( const boost::any & input )
{
float data = boost::any_cast<float> ( input );
return std::string("0");
}
static boost::any StringToInt( const boost::any & input )
{
std::string data = boost::any_caststd::string ( input );
return boost::lexical_cast<int>(data);
}
static boost::any IntToString( const boost::any & input )
{
int data = boost::any_cast<int> ( input );
return std::string("0");
}
#include "..\Math\Vector3.h"
static boost::any StringToVec3f( const boost::any & input )
{
std::string data = boost::any_caststd::string ( input );
Vec3f result;
sscanf( data.c_str(),"%f;%f;%f",&result.x,&result.y,&result.z);
return result;
}
static boost::any Vec3fToString( const boost::any & input )
{
Vec3f data = boost::any_cast<Vec3f> ( input );
std::string result;
//result += boost::lexical_caststd::string ( data.x );
result += ";";
//result += boost::lexical_caststd::string ( data.y );
result += ";";
//result += boost::lexical_caststd::string ( data.z );
return result;
}
static boost::any BoolToString( const boost::any & input )
{
bool data = boost::any_cast<bool> ( input );
if ( data )
return std::string("True");
else
return std::string("False");
}
static boost::any StringToBool( const boost::any & input )
{
std::string data = boost::any_caststd::string ( input );
if ( data == "True" || data == "true" || data == "TRUE" ||
data == "On" || data == "on" || data == "ON" )
return true;
else return false;
}
//
-----------------------------------------------------------------------------
// Automatic conversion registration
//
-----------------------------------------------------------------------------
void RegisterStandardConversions()
{
/////////////////////////////////////////////////////////////////////////////////
// HERE COMPILIATION FAILS: ( Following line )
////////////////////////////////////////////////////////////////////////////
ConversionFunction stf = &StringToFloat;
///////////////////////////////////////////////////////////////////////////////////
/// VISUAL C ERROR OUTPUT:
//////////////////////////////////////////////////////////////////////////////////
D:\Sdk\boost\boost\type_traits\is_class.hpp(78) : error C2510: 'value' :
left of '::' must be a class/struct/union
D:\Sdk\boost\boost\type_traits\is_class.hpp(94) : see reference
to class template instantiation 'boost::detail::is_class_impl<T>' being
compiled
with
[
T=boost::any (__cdecl *)(const boost::any &)
]
D:\Sdk\boost\boost\type_traits\is_stateless.hpp(31) : see
reference to class template instantiation 'boost::is_class<T>' being
compiled
with
[
T=boost::any (__cdecl *)(const boost::any &)
]
D:\Sdk\boost\boost\type_traits\is_stateless.hpp(43) : see
reference to class template instantiation
'boost::detail::is_stateless_impl<T>' being compiled
with
[
T=boost::any (__cdecl *)(const boost::any &)
]
D:\Sdk\boost\boost\function\function_base.hpp(193) : see
reference to class template instantiation 'boost::is_stateless<T>' being
compiled
with
[
T=boost::any (__cdecl *)(const boost::any &)
]
D:\Sdk\boost\boost\function\function_template.hpp(431) : see
reference to class template instantiation
'boost::detail::function::get_function_tag<F>' being compiled
with
[
F=boost::any (__cdecl *)(const boost::any &)
]
D:\Sdk\boost\boost\function\function_template.hpp(293) : see
reference to function template instantiation 'void
boost::function1::assign_to(Functor)' being compiled
with
[
R=boost::any,
T0=boost::any,
Allocator=int,
Functor=boost::any (__cdecl *)(const boost::any &)
]
\Work\FakedReality\Source\Core\Reflection\IConverter.cpp(214) :
see reference to function template instantiation
'boost::function1::function1(const Functor & )' being
compiled
with
[
R=boost::any,
T0=boost::any,
Allocator=int,
Functor=boost::any (__cdecl *)(const boost::any &)
]
D:\Sdk\boost\boost\type_traits\is_class.hpp(78) : error C2065: 'ice_not'
: undeclared identifier
D:\Sdk\boost\boost\type_traits\is_class.hpp(78) : error C2679: binary
'<' : no operator found which takes a right-hand operand of type '' (or
there is no acceptable conversion)
D:\Sdk\boost\boost\type_traits\is_class.hpp(78) : error C2955:
'boost::type_traits::ice_and' : use of class template requires template
argument list
D:\Sdk\boost\boost\type_traits\detail\ice_and.hpp(25) : see
declaration of 'boost::type_traits::ice_and'
D:\Sdk\boost\boost\type_traits\is_class.hpp(78) : error C2955:
'boost::type_traits::ice_and' : use of class template requires template
argument list
D:\Sdk\boost\boost\type_traits\detail\ice_and.hpp(25) : see
declaration of 'boost::type_traits::ice_and'
D:\Sdk\boost\boost\type_traits\is_class.hpp(78) : error C2039: 'value' :
is not a member of 'operator``global namespace'''
D:\Sdk\boost\boost\type_traits\is_class.hpp(78) : error C2065: 'value' :
undeclared identifier
D:\Sdk\boost\boost\type_traits\is_class.hpp(78) : error C2676: binary
'>' : '' does not define this operator or a conversion to a type
acceptable to the predefined operator
D:\Sdk\boost\boost\type_traits\is_class.hpp(78) : error C2056: illegal
expression
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
RegisterConversion( stf,typeofstd::string(),typeof<float>() );
ConversionFunction fts = &FloatToString;
RegisterConversion( fts,typeof<float>(),typeofstd::string() );
ConversionFunction its = &IntToString;
RegisterConversion( its,typeof<int>(),typeofstd::string() );
ConversionFunction sti = &StringToInt;
RegisterConversion( sti,typeofstd::string(),typeof<int>() );
ConversionFunction v3fts = &Vec3fToString;
RegisterConversion( v3fts,typeof<Vec3f>(),typeofstd::string() );
ConversionFunction stv3f = &StringToVec3f;
RegisterConversion( stv3f,typeofstd::string(),typeof<Vec3f>() );
ConversionFunction stb = &StringToBool;
RegisterConversion( stb,typeofstd::string(),typeof<bool> () );
ConversionFunction bts = &BoolToString;
RegisterConversion( bts,typeof<bool>(),typeofstd::string());
}
////////////////////// SECOND Problem
As you may note all conversions from data types to std::string are
commented out !
This is because boost::lexical_cast fails to compile in DEBUG mode ( it
compiles fine in RELEASE Mode
and also works like a charm in RELEASE mode )
Thanks for your time
Bernhard Glück