Форум программистов, компьютерный форум CyberForum.ru

Частичная специализация. Контейнеры - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.90
little_blond
0 / 0 / 0
Регистрация: 21.01.2012
Сообщений: 13
16.12.2012, 00:06     Частичная специализация. Контейнеры #1
Всем привет, пытаюсь разобраться с шаблонами:
Требуется создать функцию печати для stack, queue, priority_queue.

Все было бы супер, но не вижу общей для всех трех контейнеров функции доступа к элементам. Для стека и приоритетной очереди это top(), для очереди front() и back(). Получается, для очереди нужна специализация. Но возникает вопрос, каким образом задавать очередь при специализации, поскольку она сама является шаблоном, параметризованным типом контейнера и типом обрабатываемых элементов. Частичная специализация для функций, насколько мне известно, не работает(или я неправа?).

Подскажите, пожалуйста, способ реализации такого принта или ткните носом в тему, где освещалась подобная задача.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.12.2012, 00:06     Частичная специализация. Контейнеры
Посмотрите здесь:

Частичная специализация шаблона C++
явная специализация C++
C++ Явная специализация
C++ Специализация шаблона
C++ специализация шаблона
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
JlightenDev_C++
 Аватар для JlightenDev_C++
61 / 61 / 7
Регистрация: 12.08.2012
Сообщений: 150
16.12.2012, 00:59     Частичная специализация. Контейнеры #2
=> iterator
little_blond
0 / 0 / 0
Регистрация: 21.01.2012
Сообщений: 13
16.12.2012, 01:07  [ТС]     Частичная специализация. Контейнеры #3
И на что этот итератор будет "смотреть"? Как выставить его на первый элемент контейнера? Да и не работают вроде со стеками итераторы.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
16.12.2012, 01:08     Частичная специализация. Контейнеры #4
похоже речь идет о свободной функции.
и возможно частичная специализация вам и не нужна, потому как для печати вроде бы как один параметр шаблонный только - это тип контейнера. в этом случае речь идет о полной специализации, но и она не сильно нужна. для функция есть еще такая штука, как перегрузка. и вот пример именно сперегрузками, а не специализацией:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <vector>
#include <list>
#include <deque>
#include <iostream>
 
template <typename T>
void print(const T&)
{
   std::cout << "common print" << std::endl;
}
 
template <typename T>
void print(const std::vector<T>&)
{
   std::cout << "vector<T> print" << std::endl;
}
 
void print(const std::vector<char>&)
{
   std::cout << "vector<char> print" << std::endl;
}
 
int main()
{
   print(std::list<int>());
   print(std::deque<int>());
   print(std::vector<int>());
   print(std::vector<void*>());
   print(std::vector<char>());
   return 0;
}
если это не то, что надо, то непонятно, что вам надо. нужно больше инфы
little_blond
0 / 0 / 0
Регистрация: 21.01.2012
Сообщений: 13
16.12.2012, 01:17  [ТС]     Частичная специализация. Контейнеры #5
Спасибо, но, как мне кажется, не совсем то.
Задание дословно "Напишите шаблон функции для вывода значений stack, queue, priority_queue".

То есть по видимому нужен механизм, позволяющий использовать единый синтаксис для печати каждой из перечисленных сущностей. Нечто вроде:
C++
1
2
3
4
5
6
7
8
...
    stack<int, vector<int>> sv;
    queue<int, list<int>> qd;
    priority_queue<int, vector<int>, less<int>> pql;
...
    Print(sv);
    Print(qd);
    Print(pql);
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
16.12.2012, 01:20     Частичная специализация. Контейнеры #6
а вот это разве не единый синтаксис?
C++
1
2
3
4
5
  print(std::list<int>());
  print(std::deque<int>());
  print(std::vector<int>());
  print(std::vector<void*>());
  print(std::vector<char>());
вызывается функция принт. ей передается объект контейнера.
можно переписать так:

C++
1
2
3
4
5
6
7
8
9
10
11
std::list<int> c1;
std::deque<int> c2;
std::vector<int> c3;
std::vector<void*> c4;
std::vector<char> c5;
 
  print(с1);
  print(с2);
  print(с3);
  print(с4);
  print(с5);
JlightenDev_C++
 Аватар для JlightenDev_C++
61 / 61 / 7
Регистрация: 12.08.2012
Сообщений: 150
16.12.2012, 01:22     Частичная специализация. Контейнеры #7
Цитата Сообщение от little_blond Посмотреть сообщение
И на что этот итератор будет "смотреть"? Как выставить его на первый элемент контейнера? Да и не работают вроде со стеками итераторы.
.begin() & .end()
little_blond
0 / 0 / 0
Регистрация: 21.01.2012
Сообщений: 13
16.12.2012, 01:30  [ТС]     Частичная специализация. Контейнеры #8
DU,
да, все верно, спасибо! Не увидела сначала перегруженную функцию
C++
1
2
3
4
5
template <typename T>
void print(const std::vector<T>&)
{
   std::cout << "vector<T> print" << std::endl;
}
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,601
Записей в блоге: 17
16.12.2012, 01:53     Частичная специализация. Контейнеры #9
Цитата Сообщение от little_blond Посмотреть сообщение
Получается, для очереди нужна специализация.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//---------------------------------------------------------------------------
template <class C>
print(C c)
{
    while(!c.empty())
     {
         std::cout<<c.top()<<" ";
         c.pop();
     }
}
//---------------------------------------------------------------------------
template <class T>
print(std::queue<T> c)
{
    while(!c.empty())
     {
         std::cout<<c.front()<<" ";
         c.pop();
     }
}
//---------------------------------------------------------------------------
int main()
{
using namespace std;
 
stack<int> s;
 
s.push(1);
s.push(2);
s.push(3);
 
queue<int> q;
 
q.push(1);
q.push(2);
q.push(3);
 
priority_queue<int> pq;
 
pq.push(1);
pq.push(2);
pq.push(3);
 
 
print(s);  cout<<endl;
print(q);  cout<<endl;
print(pq); cout<<endl;
 
return 0;
}
3 2 1
1 2 3
3 2 1
little_blond
0 / 0 / 0
Регистрация: 21.01.2012
Сообщений: 13
16.12.2012, 11:12  [ТС]     Частичная специализация. Контейнеры #10
Avazart,
спасибо за ответ!

То есть в параметре очередь, являющаяся шаблоном от двух параметров, ( например, queue<int, list<int>>), может быть упомянута в функции как шаблон одного параметра? (queue<T>). Это было бы удобно.

Но у меня 2005 студия такой код не проглотила, ругается:
"error C2995: 'void Print(Ta &)' : function template has already been defined"

И действительно, разве такой синтаксис используется при специализации? Больше похоже на два разных шаблона с одинаковым списком параметров.

Мб дело в престарелом компиляторе? Помогите, пожалуйста, разобраться.
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,601
Записей в блоге: 17
16.12.2012, 13:12     Частичная специализация. Контейнеры #11
Ну я позабыл void понаписывать в возвращаемые значения
C++
1
2
3
4
5
6
7
//---------------------------------------------------------------------------
template <class C>
void print(C& c);
//---------------------------------------------------------------------------
template <class T>
void print(std::queue<T>& c);
//--------------------------------------------------------------------------
А вообще пример компилится на VC++2010 ( изначально писал на Builder2009)

Добавлено через 1 минуту
Цитата Сообщение от little_blond Посмотреть сообщение
И действительно, разве такой синтаксис используется при специализации? Больше похоже на два разных шаблона с одинаковым списком параметров.
Честно говоря не знаю можно ли это назвать специализацией, скорее всего перегрузка как и прошлом варианте.
little_blond
0 / 0 / 0
Регистрация: 21.01.2012
Сообщений: 13
16.12.2012, 13:58  [ТС]     Частичная специализация. Контейнеры #12
void я добляла, дело не в нем. Буду пробовать в VS 2010, спасибо
soon
 Аватар для soon
2536 / 1301 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.12.2012, 14:22     Частичная специализация. Контейнеры #13
Два раза JlightenDev_C++ сказал про итераторы. Нееет, мы будем писать костыли через top, front и прочую ерунду.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <vector>
#include <deque>
#include <set>
#include <utility>
 
template <class Container>
void print(const Container& c, std::ostream& stream = std::cout)
{
    for(const auto& elem: c)
        stream << elem << ' ';
}
 
int main()
{
    std::vector<int>    v{1, 2, 3};
    std::deque<int>     d{3, 2, 1};
    std::set<int>       s{2, 3, 1};
 
    print(v);
    std::cout << std::endl;
 
    print(d);
    std::cout << std::endl;
 
    print(s);
    std::cout << std::endl;
 
    return 0;
}
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,601
Записей в блоге: 17
16.12.2012, 14:25     Частичная специализация. Контейнеры #14
soon, Аля какие итераторы в стеке и очереди ? они закрыты ...
soon
 Аватар для soon
2536 / 1301 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
16.12.2012, 14:38     Частичная специализация. Контейнеры #15
Ладушки, мой косяк. Извините.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.12.2012, 15:20     Частичная специализация. Контейнеры
Еще ссылки по теме:

Специализация шаблона C++
C++ Специализация операции шаблона
C++ Специализация шаблона

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,601
Записей в блоге: 17
16.12.2012, 15:20     Частичная специализация. Контейнеры #16
К сожалению, в случае специализации шаблона функции все оказывается несколько сложнее по двум основным причинам.

Специализировать шаблоны функций можно только полностью, но не частично. Код, который выглядит как частичная специализация, на самом деле представляет собой перегрузку.

Специализации шаблона функции никогда не участвуют в перегрузке. Таким образом, любая написанная вами специализация никак не повлияет на результат разрешения перегрузки и выбор используемого шаблона. Это противоречит интуитивно ожидаемому поведению разрешения перегрузки. Но, в конце концов, если вы напишете нешаблонную функцию с идентичной сигнатурой вместо специализации шаблона функции, то при разрешении перегрузки будет выбрана именно нешаблонная функция, как имеющая преимущество перед шаблоном.
http://www.programmer-lib.ru/cstandart_page.php?id=30

Собственно я так и не пойму как отличить одно от другого ...
Yandex
Объявления
16.12.2012, 15:20     Частичная специализация. Контейнеры
Ответ Создать тему
Опции темы

Текущее время: 17:51. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru