Reputation: 5231
In my code, I have a lot of template algorithms where the template type must be a floating point (float
, double
, or long double
). Some of these algorithms require a default epsilon value. Example:
template <typename FloatType>
bool approx(FloatType x1, FloatType x2)
{
const FloatType epsilon; // How can I set it ?
return abs(x2 - x1) < epsilon;
}
How can I define it ? I tried the following, it's accepted by gcc, but it's not standard (and not valid in C++11). I know it's possible in C++11, but I have to be compatible with c++03.
template <typename FloatType>
struct default_epsilon
{};
template <>
struct default_epsilon<float>
{
static const float value = 1.0e-05f;
};
template <>
struct default_epsilon<double>
{
static const double value = 1.0e-10;
};
template <>
struct default_epsilon<long double>
{
static const long double value = 1.0e-12l;
};
// Then, I use it like that :
template <typename FloatType>
bool approx(FloatType x1, FloatType x2)
{
return abs(x2 - x1) < default_epsilon<FloatType>::value;
}
// or that
bool approx(FloatType x1, FloatType x2, FloatType epsilon = default_epsilon<FloatType>::value)
{
return abs(x2 - x1) < epsilon;
}
Upvotes: 1
Views: 377
Reputation: 6805
If you don't want to use std::numeric_limits<FloatType>::epsilon()
, I think you can do as proposed in comments: Initialize the static
members outside class definition.
You can write:
#include <cmath>
template <typename FloatType>
struct default_epsilon
{};
template <>
struct default_epsilon<float>
{
static const float value;
};
template <>
struct default_epsilon<double>
{
static const double value;
};
template <>
struct default_epsilon<long double>
{
static const long double value;
};
template <typename FloatType>
bool approx(FloatType x1, FloatType x2)
{
return std::abs(x2 - x1) < default_epsilon<FloatType>::value;
}
And somewhere in your .cpp file:
const float default_epsilon<float>::value = 1.0e-05f;
const double default_epsilon<double>::value = 1.0e-10;
const long double default_epsilon<long double>::value = 1.0e-12l;
And it should do the trick.
Upvotes: 2
Reputation: 650
use traditional c++ casting operator overload
class MyEpsilon
{
public:
operator float() {return 1.0e-05f;};
operator double() { return 1.0e-10; };
operator long double() { return 1.0e-12l; };
};
template<class T>
class MyTest {
public:
T DoSome() {
MyEpsilon e;
return T(e);
}
};
Upvotes: 0