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

Исключение для шаблона - C++

Восстановить пароль Регистрация
 
Linzman
0 / 0 / 0
Регистрация: 31.10.2012
Сообщений: 48
05.05.2013, 13:27     Исключение для шаблона #1
Здравствуйте ! У меня следующий вопрос : Есть база данных, написан шаблон ввода для нее
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <typename T>
        friend std::ostream& operator<<( std::ostream& os, Array<T>& cont){//
            for(int i=0;i<cont.len();i++){
                    os<<cont.get(i)<<"\t";
                os<<'\n';
            }
        return os;
        };
        template <typename T>
        friend std::istream& operator>>( std::istream& is, Array<T>& cont){
            int m;
            std::cout<<"Insert Array length";
            T a;
            std::cin>>m;
            delete[] cont.data;
            cont.data=new T [m];
            for(int i=0;i<m;i++){
                std::cout<<"Insert"<<i<<"element";
                is>>a;
                cont.set(i,a);
            }
            return is;
        };
Охото сделать исключение для шаблона в случае когда T == char , т.е. когда база имен. Просто имена удобнее вводить не посимвольно а целиком. Заранее спасибо
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
05.05.2013, 13:40     Исключение для шаблона #2
Перегрузка?
C++
1
2
std::ostream& operator<<( std::ostream& os, Array<char> const& cont) { /* ... */ }
std::istream& operator>>( std::istream& is, Array<char>& cont){ /* ... */ }
Linzman
0 / 0 / 0
Регистрация: 31.10.2012
Сообщений: 48
05.05.2013, 14:20  [ТС]     Исключение для шаблона #3
gray_fox, Пробовал. Тогда почему то ругается при вводе нечарового типа
C++ (Qt)
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
template <typename T>
        friend std::istream& operator>>( std::istream& is, Array<T>& cont){
            int m;
            std::cout<<"Insert Array length";
            T a;
            std::cin>>m;
            delete[] cont.data;
            cont.data=new T [m];
            for(int i=0;i<m;i++){
                std::cout<<"Insert"<<i<<"element";
                is>>a;
                cont.set(i,a);
            }
            return is;
        };
        friend std::ostream& operator<<( std::ostream& os, Array<char>& cont){//
            for(int i=0;i<cont.len();i++){
                    os<<cont.get(i);
                os<<'\n';
            }
        return os;
        };
        friend std::istream& operator>>( std::istream& is, Array<char>& cont){
            int m;
            std::cout<<"Insert Name length";
            char a;
            std::cin>>m;
            delete[] cont.data;
            cont.data=new char [m];
            for(int i=0;i<m;i++){
                //std::cout<<"Insert"<<i<<"element";
                is>>a;
                cont.set(i,a);
            }
            return is;
        };
error C2995: std::ostream &operator <<(std::ostream &,Array<A> &): шаблон функции уже определен
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
05.05.2013, 14:33     Исключение для шаблона #4
Linzman, прямо в шаблоне класса друзей определяешь? Возможно в этом проблема. Вот синтетический пример:
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
#include <iostream>
 
 
template<typename>
struct type {
   
   template<typename T>
   friend void f(type<T>);   
};
 
template<typename T>
void f(type<T>) {
   std::cout << "1" << std::endl;
}
 
void f(type<char>) {
   std::cout << "2" << std::endl;
}
 
 
int main() {
   type<int> t1;
   type<char> t2;
   f(t1);
   f(t2);
}
http://ideone.com/8mXE66 .
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
05.05.2013, 14:39     Исключение для шаблона #5
gray_fox, эм...специализация шаблона сопровождается пустым template<>
C++
1
2
3
4
5
6
7
8
9
template<typename T>
void f(type<T>) {
   std::cout << "1" << std::endl;
}
 
template<> 
void f(type<char>) {
   std::cout << "2" << std::endl;
}
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
05.05.2013, 14:42     Исключение для шаблона #6
Jupiter, я перегрузку предлагал. Только перегрузку для char надо тоже другом объявить, забыл.
Linzman
0 / 0 / 0
Регистрация: 31.10.2012
Сообщений: 48
05.05.2013, 14:43  [ТС]     Исключение для шаблона #7
gray_fox,
C++ (Qt)
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
#pragma once
#include "header.h"
template <typename A> class Array:
    public Container<A>{
    private:
        A* data;
        int length;
    public:
        Array<A>(int n){
        data=new A[n];
        length=n;
        }
        Array<A>(){
            data=new A[0];}
        ~Array<A>(){
        delete[] data;
        }
        void set(int j, A i){
        data[j]=i;
        }
         A get(int j){
        return data[j];
        }
        int len(){
        return length;
        }
        void operator=(Array<A> a){
            delete[] a.data;
            a=Array(length);
            for(int i=0;i<length;i++)
                a.data[i]=data[i];
        }
        Array<A> add(A a,int n){//adds a new A Element to the n position
 
        }
        int find(A a){//returns position and counts of elements inclsions
 
        }
        template <typename T> //Шаблоны работают но если T==char то имена посимвольно вводить неудобно
        friend std::ostream& operator<<( std::ostream& os, Array<T>& cont);
        template <typename T>
        friend std::istream& operator>>( std::istream& is, Array<T>& cont);
        friend std::ostream& operator<<( std::ostream& os, Array<char>& cont);
        friend std::istream& operator>>( std::istream& is, Array<char>& cont);
};
    /*class Group{
    private:
         Array<char>* name;
         Array<char>* last_name;
         int length;
    public:
        void SortByName(){}
        void SortByLastName(){}
        Array<char> GetMember(int n){}
        void SetMember(int n,char* a,char* b){}
        Array<char> ChangeMember(int n,char* a,char* b){}
    }*/
    std::ostream& operator<<( std::ostream& os, Array<char>& cont){//
            for(int i=0;i<cont.len();i++){
                    os<<cont.get(i);
                os<<'\n';
            }
        return os;
        };
    std::istream& operator>>( std::istream& is, Array<char>& cont){
            int m;
            std::cout<<"Insert Name length";
            char a;
            std::cin>>m;
            delete[] cont.data;
            cont.data=new char [m];
            for(int i=0;i<m;i++){
                //std::cout<<"Insert"<<i<<"element";
                is>>a;
                cont.set(i,a);
            }
            return is;
        };
     template <typename T> 
      std::ostream& operator<<( std::ostream& os, Array<T>& cont){//
            for(int i=0;i<cont.len();i++){
                    os<<cont.get(i)<<"\t";
                os<<'\n';
            }
        return os;
        };
     template <typename T>
       std::istream& operator>>( std::istream& is, Array<T>& cont){
            int m;
            std::cout<<"Insert Array length";
            T a;
            std::cin>>m;
            delete[] cont.data;
            cont.data=new T [m];
            for(int i=0;i<m;i++){
                std::cout<<"Insert"<<i<<"element";
                is>>a;
                cont.set(i,a);
            }
            return is;
        };
Теперь компилятор ругается "обнаружен многократно определенный символ - один или более"
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
05.05.2013, 14:57     Исключение для шаблона #8
Linzman, сделать ф-ии с char inline или вынести их реализацию в файл с исходным кодом, если это на стадии компановки.

Добавлено через 7 минут
Вообще, зачем объявлять operator << другом, ведь get и len публичные методы?

Добавлено через 2 минуты
+ перегрузка operator << вроде и не нужна совсем - код идентичный.
Linzman
0 / 0 / 0
Регистрация: 31.10.2012
Сообщений: 48
05.05.2013, 16:03  [ТС]     Исключение для шаблона #9
gray_fox,
Jupiter, Спасибо. Я сделал все как вы говорили. Теперь все выглядит так
C++ (Qt)
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
class Blabla{
 public:
template <typename T>
friend std::ostream& operator<<( std::ostream& os, Array<T>& cont)
template <typename T>
        friend std::istream& operator>>( std::istream& is, Array<T>& cont)
                       template <>
        friend std::ostream& operator<<( std::ostream& os, Array<char>& cont);
        template <>
        friend std::istream& operator>>( std::istream& is, Array<char>& cont);
}
template <typename T> 
        std::ostream& operator<<( std::ostream& os, Array<T>& cont){//
            for(int i=0;i<cont.len();i++){
                    os<<cont.get(i)<<"\t";
                os<<'\n';
            }
        return os;
        };
template <typename T>
        std::istream& operator>>( std::istream& is, Array<T>& cont){
            int m;
            std::cout<<"Insert Array length";
            T a;
            std::cin>>m;
            delete[] cont.data;
            cont.data=new T [m];
            for(int i=0;i<m;i++){
                std::cout<<"Insert"<<i<<"element";
                is>>a;
                cont.set(i,a);
            }
            return is;
        };
template <>
        std::ostream& operator<<( std::ostream& os, Array<char>& cont){//
            for(int i=0;i<cont.len();i++){
                    os<<cont.get(i);
                os<<'\n';
            }
        return os;
        };
        template <>
    std::istream& operator>>( std::istream& is, Array<char>& cont){
            int m;
            std::cout<<"Insert Name length";
            char a;
            std::cin>>m;
            delete[] cont.data;
            cont.data=new char [m];
            for(int i=0;i<m;i++){
                //std::cout<<"Insert"<<i<<"element";
                is>>a;
                cont.set(i,a);
            }
            return is;
        };
Студия пишет ошибку "operator <<: определение дружественной функции не может быть специализацией функции шаблон". Жду вашего совета
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
05.05.2013, 16:09     Исключение для шаблона #10
Цитата Сообщение от Linzman Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
class Blabla {
// ...
   template <>
   friend std::ostream& operator<<( std::ostream& os, Array<char>& cont);
   template <>
   friend std::istream& operator>>( std::istream& is, Array<char>& cont);
// ...
};
Это лишнее.
Linzman
0 / 0 / 0
Регистрация: 31.10.2012
Сообщений: 48
05.05.2013, 16:24  [ТС]     Исключение для шаблона #11
gray_fox,Убрал эти две строки в классе тогда в описании вне класса оператора std::ostream& operator<<( std::ostream& os, Array<char>& cont) компилятор ругается на то что этот оператор не друг
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
05.05.2013, 16:28     Исключение для шаблона #12
Linzman, эмм. Вот я делаю
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
#include <iostream>
 
 
template<typename>
class type {
   
   void _f() {}
   
   // объявление друга
   template<typename T>
   friend void f(type<T>);   
};
 
// шаблон ф-ии
template<typename T>
void f(type<T> t) {
   t._f();
   std::cout << "1" << std::endl;
}
 
// специализация шаблона ф-ии
template<>
void f(type<char> t) {
   t._f();
   std::cout << "2" << std::endl;
}
 
 
int main() {
   type<int> t1;
   type<char> t2;
   f(t1);
   f(t2);
}
http://ideone.com/qfyRnO
и вроде всё нормально, доступ к закрытым полям объекта есть.
Linzman
0 / 0 / 0
Регистрация: 31.10.2012
Сообщений: 48
05.05.2013, 16:40  [ТС]     Исключение для шаблона #13
gray_fox, поставил template<> перед перегруженными операторами, теперь мой код полностью идентичен вашему. Студия ругается что "обнаружен многократно определенный символ - один или более"
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.05.2013, 16:49     Исключение для шаблона
Еще ссылки по теме:

operator= для шаблона класса C++
Описать функции для шаблона вектора C++
C++ Специализация шаблона для стандартных типов

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

Или воспользуйтесь поиском по форуму:
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
05.05.2013, 16:49     Исключение для шаблона #14
Linzman, сделать специализации inline, или выносить реализацию в исходный файл. С inline
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
#include <iostream>
 
 
template<typename>
class type {
   
   void _f() {}
   
   // объявление друга
   template<typename T>
   friend void f(type<T>);   
};
 
// шаблон ф-ии
template<typename T>
void f(type<T> t) {
   t._f();
   std::cout << "1" << std::endl;
}
 
// специализация шаблона ф-ии
template<>
inline void f(type<char> t) {
   t._f();
   std::cout << "2" << std::endl;
}
 
 
int main() {
   type<int> t1;
   type<char> t2;
   f(t1);
   f(t2);
}
Yandex
Объявления
05.05.2013, 16:49     Исключение для шаблона
Ответ Создать тему
Опции темы

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