Организация структуры классов во время компиляции в соответствии с параметрами шаблона - PullRequest
0 голосов
/ 14 ноября 2011

Возможно ли в C ++ включать / исключать переменную-член на основе параметров шаблона?

Вот пример:

template< class T >
class RealNumber
{
    T real;
};

template< class T >
class ComplexNumber
{
    T real;
    T imag;
};

Поскольку они имеют много общих свойств, имея только однокласс для представления числа (с дополнительным параметром шаблона) может предотвратить некоторые дубликаты кода.

То, что я хотел сделать, это что-то вроде

template< class T , class U >
Number
{
    T real;

    // If U is not void
    U imag;
}

Так что, если второй параметр void, будетнет члена с именем imag, выдающего:

sizeof( Number< T , void > ) == sizeof( T )

Я пробовал enable_if, но не смог получить никакого результата.

Если это невозможно, есть ли какие-нибудь хаки, которые могут сделать это возможным?

Ответы [ 4 ]

1 голос
/ 14 ноября 2011

Этот ответ неполон и показывает только, как использовать enable_if для специализации шаблона класса.

template<class T,class U,class Enable = void>
class Number
{
  T real;
  T imag;
};
template<class T,class U>
class Number<T,U,typename std::enable_if<std::is_void<U>::value>::type>
{
  T real;
};

Подробная реализация зависит от точного характера проблемы.Например,

  • Если разрешено преобразование RealNumber в ComplexNumber (т.е. отношение is_a), вы можете рассмотреть возможность наследования от одной реализации к другой.
  • Чтобы повторно использовать большое количество свойствможет реализовать общую часть в частном базовом классе.
  • В зависимости от конкретной проблемы, можно проверить, действительно ли необходим их параметр шаблона U.Кроме того, какой должен быть предпочтительный синтаксис для действительного числа Number<int,void> или просто Number<int>.и т. д.
1 голос
/ 14 ноября 2011

Проверьте, пригоден ли для вас трюк наследования:

template<class T, class = void >
class RealNumber
{
  protected: T real;
};

template<class T, class U>
class ComplexNumber : public RealNumber<T>
{
  U imag;
};
1 голос
/ 14 ноября 2011
typedef NullType struct {} NullType;
template< class T , class U = NullType>
class Number
{
  T real;
  U image;
}
0 голосов
/ 14 ноября 2011

Очень сложно сказать, куда вы едете, но вот грубый скелет:

template <typename T> class Number
{
  template <typename S> class Adder
  {
    typedef S type;
    static type add(type a, type b) { return a + b; }
  };
  template <typename U, typename W> class Adder<std::pair<U,W>>
  {
    typedef typename std::pair<U,W> type;
    static type add(type a, type b) { return type(a.first + b.first, a.second + b.second); }
  };

  T val;

public:
  T operator+(const T rhs) { return Adder<T>::add(val, rhs); }
};

Обратите внимание, что большинство стандартных числовых функций библиотеки уже перегружены для типов std::complex, поэтому вы можетехочу немного подумать о том, действительно ли вам нужно написать это самостоятельно.

Использование: Number<int>, Number<double>, Number<std::pair<double, double>>.

...