#c #templates #specialization
#c #шаблоны #специализация
Вопрос:
Мне было интересно, является ли приведенная ниже частичная специализация, в которой я определяю упорядоченные и неупорядоченные списки на основе общего шаблона списка, правильным и эффективным способом сделать это.
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>{};
Спасибо,
Комментарии:
1. трудно сказать, не зная, как
List
это реализовано. Возможно, вам лучше использовать политику, которая определяет, как вставляются элементы.2. Как реализация списка повлияет на решение?
3. Как мы можем сказать вам, эффективно ли это (или правильно) или нет, не зная, как это реализовано?
4. Вы правы, но существует ли общий подход для определения того, какие классы могут быть эффективными с помощью этого метода?
Ответ №1:
Для чего-то подобного я бы использовал класс политики, чтобы определить, как вещи вставляются в один список, например
struct DefaultInsertionPolicy
{
template <typename ContainerType, typename ValueType>
static void insert(ContainerTypeamp; container, ValueType constamp; cValue)
{
container.insert(container.end(), cValue);
}
};
struct SortedInsertionPolicy
{
template <typename ContainerType, typename ValueType>
static void insert(ContainerTypeamp; container, ValueType constamp; 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 constamp; cValue)
{
InsertPolicy::insert(*this, cValue); // delegate to the policy to do the insert
}
void insert(iterator iPos, T constamp; cValue)
{
// do the real insertion at the provided position.
}
};
Таким образом, реальные типы могут быть
typedef List<some_type> UList; // insertion order
typedef List<some_type, SortedInsertionPolicy> OList; // sorted list
Ответ №2:
Я думаю, вы хотите уменьшить универсальность шаблона класса, уменьшив количество параметров шаблона для классов, которые пользователи в конечном итоге будут использовать в своем коде. Если это так, то в C 03 и C 98 это то, что вы можете сделать, т.е. Определить менее общие классы, производные от более общего класса.
Однако в C 11 вам не нужно определять новый шаблон класса. Вместо этого вы можете создавать псевдонимы шаблонов, уменьшая количество параметров шаблона одновременно с:
template <typename T>
using UList = List<T,false>;
template <typename T>
using OList = List<T,true>;
И используйте UList
and OList
, как если бы это был шаблон класса, который принимает один аргумент типа:
UList<int> uints;
OList<float> ofloats;
В вики я только что узнал этот новый способ определения типа / псевдонима, который мы использовали typedef
раньше:
Синтаксис using также может использоваться как псевдоним типа в C 11:
typedef void (*Type)(double); // Old style using OtherType = void (*)(double); // New introduced syntax