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

Как для шаблонного класса определить действие для частного случая - C++

Восстановить пароль Регистрация
 
Hrollo
34 / 34 / 6
Регистрация: 05.11.2013
Сообщений: 147
08.05.2014, 01:11     Как для шаблонного класса определить действие для частного случая #1
Всем привет. Подскажите как для шаблонного класса определить действие для частного случая.
По книге запись должна быть примерно такой:
C++
1
template<>class String<int>
но она у меня не компилируется...
вот определение общего шаблона для дружественной функции
C++
1
2
3
4
5
6
7
template<typename T>
ostream &operator<<(ostream &os,const String<T> &s)
{
    for(int i(0);i<s.length;i++)
        os<<s.str[i];
    return os;
}
а вот моя попытка сделать шаблон для типа инт
C++
1
2
3
4
5
6
7
8
9
10
template<>class String<int>
ostream &operator<<(ostream &os,const String<int> &s)
{
    for(int i(0);i<s.length;i++)
    {
        if(isdiggit(s.str[i]))
            os<<s.str[i];
    }
    return os;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.05.2014, 01:11     Как для шаблонного класса определить действие для частного случая
Посмотрите здесь:

Перегрузка оператора вывода на консоль для шаблонного класса C++
[C++] перегрузка operator<< для шаблонного класса C++
Перегрузка << , >> для шаблонного класса C++
пространство имен для шаблонного класса C++
C++ Предусмотреть использование шаблонного класса для работы с различными типами данных
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,587
08.05.2014, 01:18     Как для шаблонного класса определить действие для частного случая #2
Hrollo,
C++
1
2
3
4
5
6
7
8
9
10
template<>
std::ostream &operator<<< String<int> >(std::ostream & os, const String<int> & s)
{
    for(int i(0);i<s.length;i++)
    {
        if(isdiggit(s.str[i]))
            os<<s.str[i];
    }
    return os;
}
А что за странный такой String с int?

Добавлено через 2 минуты
Вообще, вместо специализации в этом случае, лучше и правильнее использовать перегрузку.
Hrollo
34 / 34 / 6
Регистрация: 05.11.2013
Сообщений: 147
08.05.2014, 01:23  [ТС]     Как для шаблонного класса определить действие для частного случая #3
это глупое по моему мнению задание преподавателя.
Мне надо создать шаблонный класс Строка для работы с любыми типами данных, причем у класса должно быть определено всего 3 метода не считая конструкторы и деструктор, это операция присваивания, оператор ввода в поток и оператор вывода в поток. Если чесно я не понимаю зачем вообще в данном случае использовать шаблон в данной ситуации...
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,587
08.05.2014, 01:32     Как для шаблонного класса определить действие для частного случая #4
Цитата Сообщение от Hrollo Посмотреть сообщение
Если чесно я не понимаю зачем вообще в данном случае использовать шаблон в данной ситуации...
А, это всегда так. Не надо искать смысла в таких заданиях. Они просто на изучения опр. возможности языка.
Заработало у тебя?
Hrollo
34 / 34 / 6
Регистрация: 05.11.2013
Сообщений: 147
08.05.2014, 01:39  [ТС]     Как для шаблонного класса определить действие для частного случая #5
Нет(
точнее при таком варианте ошибки компиляции больше нету
C++
1
2
3
4
5
6
7
8
9
10
template<>
ostream &operator<<(ostream &os,const String<int> &s)
{
    for(int i(0);i<s.length;i++)
    {
        if(isdigit(s.str[i]))
            os<<s.str[i];
    }
    return os;
}
Добавлено через 3 минуты
теперь заработало, все равно спасибо за отклик
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,587
08.05.2014, 01:44     Как для шаблонного класса определить действие для частного случая #6
Цитата Сообщение от Hrollo Посмотреть сообщение
точнее при таком варианте ошибки компиляции больше нету
Т.е. тот пример, который я дал, не заработал?

Цитата Сообщение от Hrollo Посмотреть сообщение
теперь заработало, все равно спасибо за отклик
Какой вариант в итоге?
Hrollo
34 / 34 / 6
Регистрация: 05.11.2013
Сообщений: 147
08.05.2014, 01:47  [ТС]     Как для шаблонного класса определить действие для частного случая #7
Да ваш вариант не заработал
C++
1
2
3
4
5
6
7
8
9
10
template<>
ostream &operator<<(ostream &os,const String<int> &s)
{
    for(int i(0);i<s.length;i++)
    {
        if(isdigit(s.str[i]))
            os<<s.str[i];
    }
    return os;
}
в таком виде все работает нормально
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,587
08.05.2014, 01:51     Как для шаблонного класса определить действие для частного случая #8
Цитата Сообщение от Hrollo Посмотреть сообщение
Да ваш вариант не заработал
Дело в том, что мой вариант 100% корректный Просто видимо что-то у тебя не так там (может скопировал не полностью или еще что).
Вот полный пример.
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
#include <iostream>
 
template <typename T>
class String
{
    //.....
};
// главный шаблон
template <typename T>
std::ostream & operator<<(std::ostream & os, const T & s)
{
//....
    return os;
}
 
// специализация - вариант из первого поста
template<>
std::ostream & operator<< <String<int> >(std::ostream & os, const String<int> & s)
{
//......
    return os;
}
 
int main() {
    String<int> s;
    
    std::cout << s;
    return 0;
}
Hrollo
34 / 34 / 6
Регистрация: 05.11.2013
Сообщений: 147
08.05.2014, 01:54  [ТС]     Как для шаблонного класса определить действие для частного случая #9
Хз копировал как у вас, и по разному переставлял в итоге подошел только мой вариант(можно сказать методом тыка на него попал).
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,587
08.05.2014, 01:55     Как для шаблонного класса определить действие для частного случая #10
Пруф.

Добавлено через 1 минуту
Цитата Сообщение от Hrollo Посмотреть сообщение
Хз копировал как у вас, и по разному переставлял в итоге подошел только мой вариант(можно сказать методом тыка на него попал).
Какой у тебя компилятор?
Hrollo
34 / 34 / 6
Регистрация: 05.11.2013
Сообщений: 147
08.05.2014, 01:58  [ТС]     Как для шаблонного класса определить действие для частного случая #11
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>
#include <cstring>
#include <cctype>
 
using namespace std;
 
template<typename T>
class String
{
private:
    char  *str;
    int length;
    const static int Max = 65535;
public:
    String();
    String(const char *s);
    String(const String &s);
    String &operator=(const String &s);
    String &operator=(const char *s);
    ~String();
    template<typename T>
    friend ostream &operator<<(ostream &os,const String &s);
    template<typename T>
    friend istream &operator>>(istream &is,String &s);
};
 
template<typename T>
String<T>::String<T>()
{
    str = NULL;
    length = 0;
}
 
template<typename T>
String<T>::String<T>(const char *s)
{
    length = strlen(s);
    str = new char[length+1];
    strcpy(str,s);
}
 
template<typename T>
String<T>::String<T>(const String<T> &s)
{
    length = s.length;
    str = new char[length+1];
    strcpy(str,s.str);
}
 
template<typename T>
String<T> &String<T>::operator=(const String<T> &s)
{
    if(this == &s)
        return *this;
    delete [] str;
    length = s.length;
    str = new char[length+1];
    strcpy(str,s.str);
    return *this;
}
 
template<typename T>
String<T> &String<T>::operator=(const char *s)
{
    delete []str;
    length = strlen(s);
    str = new char[length+1];
    strcpy(str,s);
    return *this;
}
 
 
template<typename T>
String<T>::~String<T>()
{
    delete []str;
}
 
template<typename T>
ostream &operator<<(ostream &os,const String<T> &s)
{
    for(int i(0);i<s.length;i++)
        os<<s.str[i];
    return os;
}
 
template<>
ostream &operator<<(ostream &os,const String<int> &s)
{
    for(int i(0);i<s.length;i++)
    {
        if(isdigit(s.str[i]))
            os<<s.str[i];
    }
    return os;
}
 
 
template<typename T>
istream &operator>>(istream &is,String<T> &s)
{
    char temp[String::Max];
    is.getline(temp,String::Max);
    if(is)
        s = temp;
    return is;
}
 
 
 
int main()
{
    String<int> str("1234hyu5");
    cout<<"Input string of the numb:";
 
    cout<<str<<endl;
    return 0;
}
Пишу в QtCreator но использую компилятор от 12 студии
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,587
08.05.2014, 02:09     Как для шаблонного класса определить действие для частного случая #12
Hrollo, студия это собирает. Но код содержит ошибки тем не менее.
К тому же код, который у тебя отличается от моего кардинально. Я специализировал всю функцию типом String<int>, а ты хочешь специализацию String<T>, где T = int.
В общем вот я исправил все:
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <iostream>
#include <cstring>
#include <cctype>
 
using namespace std;
 
template<typename T>
class String
{
private:
    char  *str;
    int length;
    const static int Max = 65535;
public:
    String();
    String(const char *s);
    String(const String &s);
    String &operator=(const String &s);
    String &operator=(const char *s);
    ~String();
 
    template <typename T1>
    friend ostream & operator<<(ostream &os, const String<T1> &s);
    template <typename T1>
    friend istream & operator>>(istream &is, String<T1> &s);
};
 
template<typename T>
String<T>::String()
{
    str = NULL;
    length = 0;
}
 
template<typename T>
String<T>::String(const char *s)
{
    length = strlen(s);
    str = new char[length+1];
    strcpy(str,s);
}
 
template<typename T>
String<T>::String(const String<T> &s)
{
    length = s.length;
    str = new char[length+1];
    strcpy(str,s.str);
}
 
template<typename T>
String<T> &String<T>::operator=(const String<T> &s)
{
    if(this == &s)
        return *this;
    delete [] str;
    length = s.length;
    str = new char[length+1];
    strcpy(str,s.str);
    return *this;
}
 
template<typename T>
String<T> &String<T>::operator=(const char *s)
{
    delete []str;
    length = strlen(s);
    str = new char[length+1];
    strcpy(str,s);
    return *this;
}
 
 
template<typename T>
String<T>::~String()
{
    delete []str;
}
 
template <typename T>
ostream &operator<<(ostream &os, const String<T> &s)
{
    for(int i(0);i<s.length;i++)
        os<<s.str[i];
    return os;
}
 
template<>
ostream & operator<< <int>(ostream &os, const String<int> &s) //<-- вариант работает
{
    for(int i(0);i<s.length;i++)
    {
        if(isdigit(s.str[i]))
            os<<s.str[i];
    }
    return os;
}
 
 
template <typename T>
istream &operator>>(istream &is, String<T> & s)
{
    char temp[String<T>::Max];
    is.getline(temp,String<T>::Max);
    if(is)
        s = temp;
    return is;
}
 
 
 
int main()
{
    String<int> str("1234hyu5");
    cout<<"Input string of the numb:";
 
    cout<<str<<endl;
    return 0;
}
Hrollo
34 / 34 / 6
Регистрация: 05.11.2013
Сообщений: 147
08.05.2014, 02:22  [ТС]     Как для шаблонного класса определить действие для частного случая #13
Я это и имел ввиду с самого начала, может бытьб просто неправильно выразился.
Ваш вариант заработал
DrOffset
6423 / 3797 / 878
Регистрация: 30.01.2014
Сообщений: 6,587
08.05.2014, 02:28     Как для шаблонного класса определить действие для частного случая #14
Hrollo, на будущее: cl (компилятор из студии) весьма своеобразно обрабатывает шаблонный код. Откладывает его разбор до полного инстанцирования (подстановки аргументов). Следовательно, до тех пор пока шаблонная функция не вызывается, внутри можно написать полную ахинею и компилятор прожует.
Некоторые, кстати, считают, что это хорошо. Однако на данный момент такое поведение не соответствует стандарту С++
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.05.2014, 02:34     Как для шаблонного класса определить действие для частного случая
Еще ссылки по теме:

C++ Какой должен быть синтаксис для использования вложенного шаблонного класса?
Оператор индексации и присваивания для шаблонного класса Vector C++ C++
Вызов метода у шаблонного поля, шаблонного класса C++

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

Или воспользуйтесь поиском по форуму:
Hrollo
34 / 34 / 6
Регистрация: 05.11.2013
Сообщений: 147
08.05.2014, 02:34  [ТС]     Как для шаблонного класса определить действие для частного случая #15
спасибо за объяснения
Yandex
Объявления
08.05.2014, 02:34     Как для шаблонного класса определить действие для частного случая
Ответ Создать тему
Опции темы

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