Программирование. Принципы и практика использования C++ Исправленное издание, стр. 260
array<int,256> gb; // 256 целых чиселarray<double,6> ad = { 0.0, 1.1, 2.2, 3.3, 4.4, 5.5 }; // инициализатор!const int max = 1024;void some_fct(int n){ array<char,max> loc; array<char,n> oops; // ошибка: значение n компилятору // неизвестно // ... array<char,max> loc2 = loc; // создаем резервную копию // ... loc = loc2; // восстанавливаем // ...}Ясно, что класс array очень простой — более простой и менее мощный, чем класс
vectorvectorgblocarrayПоставим противоположный вопрос: “Почему бы просто не использовать класс
vectorarrayvectordouble* p = ad; // ошибка: нет неявного преобразования // в указательdouble* q = ad.data(); // OK: явное преобразованиеtemplate<class C> void printout(const C& c) // шаблонная функция{ for (int i = 0; i<c.size(); ++i) cout << c[i] <<'\n';Эту функцию
printout()arrayvectorprintout(ad); // вызов из класса arrayvector<int> vi;// ...printout(vi); // вызов из класса vectorЭто простой пример обобщенного программирования, демонстрирующий доступ к данным. Он работает благодаря тому, что как для класса
arrayvectorsize()19.3.5. Вывод шаблонных аргументов
Создавая объект конкретного класса на основе шаблонного класса, мы указываем шаблонные аргументы. Рассмотрим пример.
array<char,1024> buf; // для массива buf параметр T — char, а N == 1024array<double,10> b2; // для массива b2 параметр T — double, а N == 10
template<class T, int N> void fill(array<T,N>& b, const T& val){ for (int i = 0; i<N; ++i) b[i] = val;}void f(){ fill(buf, 'x'); // для функции fill() параметр T — char, // а N == 1024, // потому что аргументом является объект buf fill(b2,0.0); // для функции fill() параметр T — double, // а N == 10, // потому что аргументом является объект b2}С формальной точки зрения вызов
fill(buf,'x')fill<char,1024>(buf,'x')fill(b2,0)fill<double,10>(b2,0)19.3.6. Обобщение класса vector
Когда мы создавали обобщенный класс
vectorvectordoublevectorTpush_back()resize()reserve()double