Как создать экземпляр с параметрами, отличными от значений по умолчанию, в параметре шаблона шаблона - PullRequest
0 голосов
/ 31 марта 2011

Я пытаюсь закрепить мое понимание параметров шаблона шаблона. В шаблонах C ++ Полное руководство (Vandervoorde, Josuttis) на странице 52 приведен пример, который я хочу использовать, как показано на этом рисунке:

codeSnippet

(я также пытаюсь узнать, как использовать изображения из Picasa в stackoverflow, поэтому, если вышеприведенное не сработает, вот немного более подробная версия)

Оригинальный код из Книги

template <typename T,
          template <typename ELEM, typename ALLOC=std::allocator<ELEM> > class CONT=std::vector>
class Stack
{
    private:
        CONT<T >  elems; //Why doesn't CONT<T, ALLOC> elems; compile?
};

Не показывает, как использовать это для другого распределителя. Они показывают другой контейнер как:

Stack<int, std::deque> my_deque_stack;

и в своей наивности я попробовал:

Stack<int, std::deque<int,  std::allocator<int> >  > my_deque_int_stack;

Я также пытался в приватном разделе определить CONT как

CONT<T, ALLOC>

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

1 Ответ

1 голос
/ 31 марта 2011

Определения параметров внутри CONT на самом деле не используются компилятором. Параметр шаблона-шаблона CONT на самом деле похож на функцию, которая принимает 2 типа ввода и возвращает новый тип:

// pseudo code
type Stack(type T, type(*CONT)(type ELEM, type ALLOC = etc)) { 
   return CONT(T);
}

и, как и обычные объявления указателей на функции, имена ELEM, ALLOC фактически игнорируются компилятором.

То, что видит компилятор, будет просто

template <typename T,
          template <typename E, typename = std::allocator<E> > class CONT = std::vector>
struct Stack { ... };

Следовательно, вы не можете использовать ALLOC вообще.


Так, чтобы решить это? Ну, вы передаете дополнительный параметр! Как и в случае с обычной функцией C ++:

// pseudo code
type Stack(type T, type(*CONT)(type, type), type ALLOCATOR = etc) { 
//                                          ^^^^^^^^^^^^^^^^^^^^
   return CONT(T, ALLOCATOR);
}

Соответствующее фактическое объявление шаблона будет

template <typename T,
          template <typename, typename> class CONT = std::vector,
          typename ALLOCATOR = std::allocator<T> >
//        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
struct Stack {
   ...
   CONT<T, ALLOCATOR> elems;
};

//...
Stack<int, std::vector, std::allocator<int> > s;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...