Как можно использовать параметры шаблона шаблона?

Я видел несколько примеров C++, использующих 9X_templates параметры шаблона шаблона (то есть шаблоны, которые 9X_template принимают шаблоны в качестве параметров) для 9X_cpp создания классов на основе политик. Как 9X_cxx еще можно использовать эту технику?

307
1

  • Я пришел с другого направления (FP, ...
10
Общее количество ответов: 10

Ответ #1

Ответ на вопрос: Как можно использовать параметры шаблона шаблона?

Я думаю, вам нужно использовать синтаксис 9X_templates шаблона шаблона для передачи параметра, тип 9X_template которого является шаблоном, зависящим от 9X_template другого шаблона, например этого:

template  class H, class S>
void f(const H &value) {
}

Здесь H - шаблон, но 9X_c++ я хотел, чтобы эта функция работала со всеми 9X_templates специализациями H.

ПРИМЕЧАНИЕ. Я программировал на C++ много 9X_cxx лет, и мне это понадобилось только один 9X_cpp раз. Я считаю, что это редко используемая 9X_template-templates функция (конечно, удобная, когда она вам 9X_template-templates нужна!).

Я пытался придумать хорошие примеры, и, честно 9X_cpp говоря, в большинстве случаев в этом нет 9X_template необходимости, но давайте придумаем пример. Представим, что 9X_cxx std::vector не имеет typedef value_type.

Итак, как бы вы написали функцию, которая 9X_c++ может создавать переменные правильного типа 9X_c++ для векторных элементов? Это сработает.

template  class V, class T, class A>
void f(V &v) {
    // This can be "typename V::value_type",
    // but we are pretending we don't have it

    T temp = v.back();
    v.pop_back();
    // Do some work on temp

    std::cout << temp << std::endl;
}

ПРИМЕЧАНИЕ. std::vector имеет 9X_templates два параметра шаблона, тип и распределитель, поэтому 9X_c++ нам пришлось принять их оба. К счастью, из-за 9X_cpp вывода типа нам не нужно явно указывать 9X_template-templates точный тип.

который можно использовать так:

f(v); // v is of type std::vector using any allocator

или 9X_templates еще лучше, мы можем просто использовать:

f(v); // everything is deduced, f can deal with a vector of any type!

ОБНОВЛЕНИЕ. Даже 9X_c++ этот надуманный пример, хотя и является 9X_template-templates иллюстративным, больше не является прекрасным 9X_template-templates из-за того, что в C++ 11 введен auto. Теперь 9X_templates ту же функцию можно записать как:

template 
void f(Cont &v) {

    auto temp = v.back();
    v.pop_back();
    // Do some work on temp

    std::cout << temp << std::endl;
}

именно 9X_templates так я бы предпочел написать этот тип кода.

253
3

  • Что ж, вам не нужно предоставлять распределитель. Важно то, что параметр шаблона шаблона был определен с правильным количеством аргументов. Но функция не должна заботиться об их «типах» или значении, в C++ ...

Ответ #2

Ответ на вопрос: Как можно использовать параметры шаблона шаблона?

На самом деле, вариант использования параметров 9X_templates шаблона достаточно очевиден. Как только 9X_c++ вы узнаете, что в C++ stdlib есть зияющая 9X_templates дыра в том, что не определены операторы 9X_c++ вывода потока для стандартных типов контейнеров, вы 9X_template-templates можете приступить к написанию чего-то вроде:

template
static inline std::ostream& operator<<(std::ostream& out, std::list const& v)
{
    out << '[';
    if (!v.empty()) {
        for (typename std::list::const_iterator i = v.begin(); ;) {
            out << *i;
            if (++i == v.end())
                break;
            out << ", ";
        }
    }
    out << ']';
    return out;
}

Тогда 9X_cpp вы поймете, что код для вектора такой же, для 9X_cpp forward_list такой же, на самом деле, даже 9X_templates для множества типов карт он остается неизменным. Эти 9X_templates классы шаблонов не имеют ничего общего, кроме 9X_cxx метаинтерфейса / протокола, и использование 9X_template-templates параметра шаблона шаблона позволяет зафиксировать 9X_template-templates общность во всех из них. Однако прежде чем 9X_cpp приступить к написанию шаблона, стоит проверить 9X_cpp ссылку, чтобы вспомнить, что контейнеры 9X_cxx последовательности принимают 2 аргумента 9X_cxx шаблона - для типа значения и распределителя. Хотя 9X_c++ распределитель установлен по умолчанию, мы 9X_cpp все равно должны учитывать его существование 9X_cxx в нашем шаблоне operator <<:

template