Объявление необязательного поля класса с использованием шаблонов в C ++ - PullRequest
0 голосов
/ 08 мая 2020

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

Теперь в одном из классов я пытаюсь сделать что-то вроде этого ...

template<typename Filter, typename Compensation.....> 
class MeasurementChannel {

private:
  if constexpr( !std::is_same<Compensation, void>){
    Compensation _comp; // this is an optional field
  }

  ....

  ....

};

Теперь это не работает, и в реальном примере у меня может быть 4+ различных подключаемых компонента, таких как Компенсация, что делает частичную специализацию проблемой, потому что мне понадобится 16 специализаций, чтобы иметь дело с различными комбинациями пустоты в каждая из дополнительных позиций.

Лучший способ, который я придумал до сих пор, - это создать нулевой класс (в данном случае NullComp), который реализует интерфейс basi c, но ничего не делает и заменяется пользователем, когда он не хочет функциональность этого компонента как часть шаблонного класса. В зависимости от уровня оптимизации компилятора большая часть генерируемого кода оптимизируется, но я хотел бы иметь возможность гарантировать, что вообще ничего не будет создано. .

Итак, мой вопрос в основном сводится к тому, есть ли в шаблонах какой-либо способ необязательного объявления поля как части класса. Т.е. есть какая-то техника, которая дает эквивалент использования std :: enable_if с методами.

В качестве альтернативы я просто пытаюсь сделать это неправильно, и есть простой элегантный способ создания шаблонов, который достигает той же конечной цели, используя какая-то совершенно другая техника.

Ответы [ 2 ]

1 голос
/ 08 мая 2020

Вот возможное решение, используя условное наследование.

template<bool Enable>
struct field_1 {};

template<>
struct field_1<true> { t1 member1; };

template<bool Enable, bool Enable1>
struct field_2 : field_1<Enable1> {};

template<bool Enable1>
struct field_2<true, Enable1> : field_1<Enable1> { t2 member2; };

template<bool Enable2, bool Enable1>
struct main_type : field_2<Enable2, Enable1> {
    // body
};

Это становится громоздким для слишком большого количества полей. Возможно, есть способ сделать этот вариант c, о котором я не думаю.

1 голос
/ 08 мая 2020
  1. Вы можете его частично специализировать:
template<class Filter> class MeasurementChannel<Filter, void> {};
В качестве альтернативы, чтобы не копировать весь код класса в частичную специализацию, вы можете специализировать только соответствующую часть:
template<class Compensation> class CompHolder {
protected:
    Compensation comp; // don't start identifiers with underscores
};

template<> class CompHolder<void> {};

template<class Filter, class Compensation> class MeasurementChannel
    : CompHolder<Compensation>
{
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...