Представьте, что у вас есть несколько классов, и все они содержат статические переменные одного и того же значения, но их имена различаются в разных классах.
Пример игрушки:
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;
};
Я хочу обернуть переменную «size» дочерним элементом std::integral_constant
. Обратите внимание, что я не могу редактировать классы Point, потому что они являются частью некоторых внешних библиотек. Эта реализация работает для меня, но выглядит неуклюже (я использую 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> { };
Есть ли способ пропустить все эти HasSomeVars
и получить что-то короткое и ясное, как это:
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> { };
Этот код получает ошибку компиляции:
Ошибка C2953: «Размер »: шаблон класса уже определен