Imagine that you have several classes and all of them contain a static variable of the same meaning, but it's names differ in different classes.
A toy example:
class Point2D
{
public:
static constexpr int dimension = 2;
private:
double x, y;
}
class Point3D
{
public:
static constexpr int dim = 3;
private:
double x, y, z;
};
I want to wrap a "dimension" variable with a std::integral_constant
's child. Note that I can't edit 'Point' classes, because they are parts of some external libraries. This implementation works for me, but looks clumsy (I'm using VS2017):
template <typename T, typename = void>
struct HasDimensionVar : std::false_type { };
template <typename T>
struct HasDimensionVar<T, decltype( T::dimension, void( ) )> : std::true_type { };
template <typename T, typename = void>
struct HasDimVar : std::false_type { };
template <typename T>
struct HasDimVar<T, decltype( T::dim, void( ) )> : std::true_type { };
template <typename T, class Enable = void>
struct Dimension;
template <typename T>
struct Dimension<T, std::enable_if_t< HasDimensionVar<T>::value> > :
std::integral_constant<decltype( T::dimension ), T::dimension> { };
template <typename T>
struct Dimension<T, std::enable_if_t< HasDimVar<T>::value> > :
std::integral_constant<decltype( T::dim ), T::dim> { };
Is there a way to skip all these HasSomeVars
and have something short and clear like this:
template <typename T, class Enable = void>
struct Dimension;
template <typename T>
struct Dimension<T, decltype( T::dimension, void( ) ) > :
std::integral_constant<decltype( T::dimension ), T::dimension> { };
template <typename T>
struct Dimension<T, decltype( T::dim, void( ) ) > :
std::integral_constant<decltype( T::dim ), T::dim> { };
This code gets a compile error:
Error C2953: 'Dimension< T, unknown-type >': class template has already been defined