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

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

307
1

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

Ответ #1

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

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

template 

              
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

              
185
6

  • Это самый пробуждающий для меня ответ в шаблонах C++. @WhozCraig Как вы узнали ...

Ответ #3

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

Вот простой пример, взятый из 'Modern C++ Design - Generic Programming and Design Patterns Applied' Андрея Александреску:

Он 9X_template-templates использует классы с параметрами шаблона 9X_template шаблона для реализации шаблона политики:

// Library code template 

              
76
1

  • В вопросе конкретно запрашиваются примеры, отличные от шабло ...

Ответ #4

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

Вот еще один практический пример из моего 9X_template CUDA Convolutional neural network library. У меня есть следующий шаблон класса:

template class Tensor 

, который 9X_template-templates на самом деле реализует манипуляции с n-мерными 9X_template-templates матрицами. Также существует шаблон дочернего 9X_template класса:

template class TensorGPU : public Tensor 

, который реализует те же функции, но 9X_cpp в графическом процессоре. Оба шаблона могут 9X_cxx работать со всеми основными типами, такими 9X_template как float, double, int и т. Д. А еще у меня 9X_template-templates есть шаблон класса (упрощенный):

template 

              
21
0

Ответ #5

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

Допустим, вы используете CRTP для предоставления 9X_template-templates «интерфейса» для набора дочерних шаблонов; и 9X_templates родительский, и дочерний элементы являются 9X_template-templates параметрическими в другом (-ых) аргументе 9X_cxx (-ах) шаблона:

template class interface { void do_something(VALUE v) { static_cast(this)->do_something(v); } }; template class derived : public interface { void do_something(VALUE v) { ... } }; typedef interface, int> derived_t; 

Обратите внимание на дублирование 9X_template int, которое на самом деле является параметром 9X_template одного и того же типа, указанным для обоих 9X_templates шаблонов. Вы можете использовать шаблон 9X_cpp шаблона для DERIVED, чтобы избежать этого 9X_template дублирования:

template 

              
13
0

Ответ #6

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

Вот с чем я столкнулся:

template class B { A& a; }; template class A { B b; }; class AInstance : A>>>>>>> { }; 

Можно решить, чтобы:

template class B { A& a; }; template< template class B> class A { B b; }; class AInstance : A //happy { }; 

или 9X_template (рабочий код):

template class B { public: A* a; int GetInt() { return a->dummy; } }; template< template class B> class A { public: A() : dummy(3) { b.a = this; } B b; int dummy; }; class AInstance : public A //happy { public: void Print() { std::cout << b.GetInt(); } }; int main() { std::cout << "hello"; AInstance test; test.Print(); } 


12
0

Ответ #7

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

Вот одно обобщение из того, что я только 9X_templates что использовал. Я публикую его, так как 9X_cxx это очень простой пример, и он демонстрирует 9X_cxx практический вариант использования вместе 9X_c++ с аргументами по умолчанию:

#include template class Alloc final { /*...*/ }; template 

              
5
0

Ответ #8

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

В решении с вариативными шаблонами, предоставленным 9X_cpp pfalcon, мне было трудно на самом деле специализировать 9X_template оператор ostream для std :: map из-за жадной 9X_templates природы вариативной специализации. Вот небольшая 9X_template доработка, которая у меня сработала:

#include #include #include #include #include 
    namespace containerdisplay { template class C, class... Args> std::ostream& operator <<(std::ostream& os, const C& objs) { std::cout << __PRETTY_FUNCTION__ << '\n'; for (auto const& obj : objs) os << obj << ' '; return os; } } template< typename K, typename V> std::ostream& operator << ( std::ostream& os, const std::map< K, V > & objs ) { std::cout << __PRETTY_FUNCTION__ << '\n'; for( auto& obj : objs ) { os << obj.first << ": " << obj.second << std::endl; } return os; } int main() { { using namespace containerdisplay; std::vector vf { 1.1, 2.2, 3.3, 4.4 }; std::cout << vf << '\n'; std::list lc { 'a', 'b', 'c', 'd' }; std::cout << lc << '\n'; std::deque di { 1, 2, 3, 4 }; std::cout << di << '\n'; } std::map< std::string, std::string > m1 { { "foo", "bar" }, { "baz", "boo" } }; std::cout << m1 << std::endl; return 0; }  


4
0

Ответ #9

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

Это улучшает читаемость вашего кода, обеспечивает 9X_c++ дополнительную безопасность типов и экономит 9X_templates некоторые усилия компилятора.

Допустим, вы 9X_template хотите распечатать каждый элемент контейнера, вы 9X_templates можете использовать следующий код без параметра 9X_cpp шаблона шаблона

template void print_container(const T& c) { for (const auto& v : c) { std::cout << v << ' '; } std::cout << '\n'; } 

или с параметром шаблона 9X_template шаблона

template< template class ContainerType, typename ValueType, typename AllocType> void print_container(const ContainerType& c) { for (const auto& v : c) { std::cout << v << ' '; } std::cout << '\n'; } 

Предположим, вы передаете целое число, например 9X_templates print_container(3). В первом случае экземпляр шаблона будет 9X_c++ создан компилятором, который будет жаловаться 9X_cpp на использование c в цикле for, последний 9X_cpp не будет создавать экземпляр шаблона вообще, поскольку 9X_cxx не может быть найден подходящий тип.

Вообще 9X_cxx говоря, если ваш класс / функция шаблона 9X_c++ предназначен для обработки класса шаблона 9X_templates как параметра шаблона, лучше прояснить это.

3
0

Ответ #10

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

Я использую его для версионных типов.

Если 9X_template у вас есть тип, версионированный с помощью 9X_cxx шаблона, такого как MyType, вы можете написать 9X_cxx функцию, в которой вы можете фиксировать 9X_cxx номер версии:

template

              
3
0