J
Jens Thoms Toerring
Hi,
I need a class that behaves in most respects like a normal
double. The only differences are in the comparison operators
(implementing "fuzzy" comparisons instead of exact ones) and
a small number of extra functions as well. As far as I can
see operators only make sense when they apply to other in-
stances of the class and to arithmetic types. So set out with
something like this:
------------8<-----------------------------------------------
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
using boost::enable_if_c;
using boost::is_arithmetic;
class FuzzyDouble {
private:
double m_value;
static double s_epsilon;
public:
FuzzyDouble( double value = 0.0 ) : m_value( value ) { }
bool operator == ( FuzzyDouble const & rhs ) const
{
return m_value > rhs.m_value - s_epsilon
&& m_value < rhs.m_value + s_epsilon;
}
template< typename T > bool
operator == ( typename enable_if_c< is_arithmetic< T >::value, T >::type
const & rhs ) const
{
return *this == FuzzyDouble( rhs );
}
// Further comparison operators left out for brevitities sake...
FuzzyDouble operator + ( FuzzyDouble const & rhs ) const
{
return FuzzyDouble( m_value ) += rhs;
}
template< typename T> FuzzyDouble
operator + ( typename enable_if_c< is_arithmetic< T >::value, T >::type
const & rhs ) const
{
return FuzzyDouble( m_value ) += rhs;
}
FuzzyDouble & operator += ( FuzzyDouble const & rhs )
{
m_value += rhs.m_value;
return *this;
}
template< typename T > FuzzyDouble &
operator += ( typename enable_if_c< is_arithmetic< T >::value, T >::type
const & rhs ) const
{
m_value += rhs.value;
return *this;
}
// Further arithmetic operators left out for brevities sake...
double value( ) const { return m_value; }
};
double FuzzyDouble::s_epsilon = 1.0e-8;
------------8<-----------------------------------------------
Beside this I obviously also need functions like this:
------------8<-----------------------------------------------
template< typename T > bool
operator == ( T const & lhs, FuzzyDouble const & rhs )
{
return rhs == lhs;
}
template< typename T > FuzzyDouble
operator + ( T const & lhs, FuzzyDouble const & rhs )
{
return rhs + lhs;
}
------------8<-----------------------------------------------
Now I also would like to restrict the types that can be used for
these functions to arithmetic types (if I don't the compiler
complains at a few places in my program I want to use this for
about ambigious overloads). But while this works nicely for the
member functions I didn't fin any way to do that yet for the non-
member functions. If I for example try as above
template< typename T > bool
operator == ( typename enable_if_c< is_arithmetic< T >::value, T >::type
const & lhs, FuzzyDouble const & rhs )
{
return rhs == lhs;
}
the compiler doesn't complain but never considers them at all.
Thus at the moment it looks as I if would need at least five
functions with identical bodies for the arithmetic types int,
long and their unsigned counterparts as well as for double. This
looks extremely ugly to me (and increases the risk for mistakes
considerably). Does someone has an idea how I can do it correctly?
Another question is of course if the whole idea is completely
stupid. Are there better ways to achieve what I want?
Best regards, Jens
I need a class that behaves in most respects like a normal
double. The only differences are in the comparison operators
(implementing "fuzzy" comparisons instead of exact ones) and
a small number of extra functions as well. As far as I can
see operators only make sense when they apply to other in-
stances of the class and to arithmetic types. So set out with
something like this:
------------8<-----------------------------------------------
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
using boost::enable_if_c;
using boost::is_arithmetic;
class FuzzyDouble {
private:
double m_value;
static double s_epsilon;
public:
FuzzyDouble( double value = 0.0 ) : m_value( value ) { }
bool operator == ( FuzzyDouble const & rhs ) const
{
return m_value > rhs.m_value - s_epsilon
&& m_value < rhs.m_value + s_epsilon;
}
template< typename T > bool
operator == ( typename enable_if_c< is_arithmetic< T >::value, T >::type
const & rhs ) const
{
return *this == FuzzyDouble( rhs );
}
// Further comparison operators left out for brevitities sake...
FuzzyDouble operator + ( FuzzyDouble const & rhs ) const
{
return FuzzyDouble( m_value ) += rhs;
}
template< typename T> FuzzyDouble
operator + ( typename enable_if_c< is_arithmetic< T >::value, T >::type
const & rhs ) const
{
return FuzzyDouble( m_value ) += rhs;
}
FuzzyDouble & operator += ( FuzzyDouble const & rhs )
{
m_value += rhs.m_value;
return *this;
}
template< typename T > FuzzyDouble &
operator += ( typename enable_if_c< is_arithmetic< T >::value, T >::type
const & rhs ) const
{
m_value += rhs.value;
return *this;
}
// Further arithmetic operators left out for brevities sake...
double value( ) const { return m_value; }
};
double FuzzyDouble::s_epsilon = 1.0e-8;
------------8<-----------------------------------------------
Beside this I obviously also need functions like this:
------------8<-----------------------------------------------
template< typename T > bool
operator == ( T const & lhs, FuzzyDouble const & rhs )
{
return rhs == lhs;
}
template< typename T > FuzzyDouble
operator + ( T const & lhs, FuzzyDouble const & rhs )
{
return rhs + lhs;
}
------------8<-----------------------------------------------
Now I also would like to restrict the types that can be used for
these functions to arithmetic types (if I don't the compiler
complains at a few places in my program I want to use this for
about ambigious overloads). But while this works nicely for the
member functions I didn't fin any way to do that yet for the non-
member functions. If I for example try as above
template< typename T > bool
operator == ( typename enable_if_c< is_arithmetic< T >::value, T >::type
const & lhs, FuzzyDouble const & rhs )
{
return rhs == lhs;
}
the compiler doesn't complain but never considers them at all.
Thus at the moment it looks as I if would need at least five
functions with identical bodies for the arithmetic types int,
long and their unsigned counterparts as well as for double. This
looks extremely ugly to me (and increases the risk for mistakes
considerably). Does someone has an idea how I can do it correctly?
Another question is of course if the whole idea is completely
stupid. Are there better ways to achieve what I want?
Best regards, Jens