Шаблонная специализация для флагов классов - PullRequest
2 голосов
/ 01 ноября 2011

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

template <typename T, bool O> class List;                                       
template <typename T> class UList: public List<T,false>{};                      
template <typename T> class OList: public List<T,true>{};

Спасибо,

Ответы [ 2 ]

3 голосов
/ 01 ноября 2011

Для чего-то подобного, я бы использовал класс политики, чтобы определить, как вещи вставляются в один список, например,

struct DefaultInsertionPolicy
{
  template <typename ContainerType, typename ValueType>
  static void insert(ContainerType& container, ValueType const& cValue)
  {
    container.insert(container.end(), cValue);
  }
};

struct SortedInsertionPolicy
{
  template <typename ContainerType, typename ValueType>
  static void insert(ContainerType& container, ValueType const& cValue)
  {
    // I'm using lower_bound here, but do what is necessary for you
    typename ContainerType::iterator ft = std::lower_bound(container.begin(), container.end(), cValue);
    container.insert(ft, cValue);
  }
};

template <typename T, typename InsertPolicy = DefaultInsertionPolicy>
class List
{
  :
  // insert function
  void insert(T const& cValue)
  {
    InsertPolicy::insert(*this, cValue); // delegate to the policy to do the insert
  }

  void insert(iterator iPos, T const& cValue)
  {
    // do the real insertion at the provided position.
  }
};

Таким образом, реальные типы могут быть

typedef List<some_type> UList; // insertion order
typedef List<some_type, SortedInsertionPolicy> OList; // sorted list
1 голос
/ 01 ноября 2011

Я думаю, что вы хотите уменьшить универсальность шаблона класса, уменьшив количество параметров шаблона для классов, которые пользователи в конечном итоге будут использовать в своем коде. Если это так, то в C ++ 03 и C ++ 98 это то, что вы можете сделать, т.е. определить менее универсальные классы, происходящие из более универсального класса.

Однако в C ++ 11 вам не нужно определять новый шаблон класса. Вместо этого вы можете создать псевдонимов шаблонов , уменьшая количество параметров шаблона одновременно с:

template <typename T> 
using UList = List<T,false>;                      

template <typename T> 
using OList = List<T,true>;

И использовать UList и OList, как если бы это был шаблон класса, который принимает один аргумент типа:

UList<int> uints;
OList<float> ofloats;

В вики я только что узнал этот новый способ определения типа / псевдонима, который мы раньше использовали с помощью typedef до:

Синтаксис using может также использоваться в качестве псевдонима типа в C ++ 11:

typedef void (*Type)(double);         // Old style
using OtherType = void (*)(double);   // New introduced syntax
...