Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
DiffEreD
1431 / 768 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
#1

Перегрузка оператора шаблонного класса в зависимости от типа - C++

06.12.2012, 14:08. Просмотров 992. Ответов 5

Как заставить шаблон различать тип переменной которую ему передают? Пробую определить через type_traits, но не выходит - не компилируется. Хочу перегрузить operator+= как для разных объектов класса так и для встроенных типов. Вот небольшой пример моего кода:
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
#include <iostream>
#include <type_traits>
 
template<typename T>
class foo
{
    T m_somevalue;
public:
    foo() : m_somevalue(10) {}
    T get() const {return m_somevalue;}
    void show() const {std::cout<<m_somevalue<<std::endl;}
 
    template<typename U>
    foo& operator+=(const U val) //foo+=foo or foo+=val(int, long, double)
    {
        if (std::is_class<U>::value)
        {
            m_somevalue+=val.get();
            return *this;
        }
        else
        {
            m_somevalue+=val;
            return *this;
        }
    }
};
 
 
int main()
{
    foo<int> a, b;  
    foo<long> d;
    a.show();       //10
    b.show();       //10
    d.show();       //10
    (a+=b).show();  
    (a+=d).show();  
    (a+=5).show();
 
    system("pause");
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.12.2012, 14:08
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Перегрузка оператора шаблонного класса в зависимости от типа (C++):

Перегрузка оператора << шаблонного класса - C++
Всем доброго времени суток! Целый день бьюсь над перегрузкой оператора &lt;&lt; в шаблонном классе одномерный массив. Пока получилось родить...

Перегрузка оператора -> для шаблонного класса - C++
Здравствуйте! Возникла проблема: не могу додуматься как перегрузить оператор -&gt; так, чтобы он корректно работал. Вот код: template&lt;class...

Перегрузка оператора вывода на консоль для шаблонного класса - C++
Следующий код компилируется, но не линкуется: #include &lt;iostream&gt; using namespace std; template &lt;typename T&gt; class A { ...

Перегрузить operator<<() для шаблонного класса (перегрузка оператора вывода) - C++
Здравствуйте. Перегружаю оператор вывода для шаблонного класса. using namespace std; template &lt;class Element&gt; class List { ...

Различное поведение конструктора шаблонного класса в зависимости от типа параметра - C++
Здравствуйте. Возникла проблема - при попытке изменить поведение конструктора шаблонного класса (структуры) в зависимости от типа...

Перегрузка << , >> для шаблонного класса - C++
Доброго времени суток всем! Данная тема не раз подымалась на форуме.. Но есть но.. Помогите перегрузить операторы побитового сдвига для...

5
gray_fox
What a waste!
1522 / 1227 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
06.12.2012, 14:44 #2
Перегрузка?
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
#include <iostream>
// #include <type_traits>
 
template<typename T>
class foo
{
    T m_somevalue;
public:
    foo() : m_somevalue(10) {}
    T get() const {return m_somevalue;}
    void show() const {std::cout<<m_somevalue<<std::endl;}
 
//    template<typename U>
//    foo& operator+=(const U val) //foo+=foo or foo+=val(int, long, double)
//    {
//        if (std::is_class<U>::value)
//        {
//            m_somevalue+=val.get();
//            return *this;
//        }
//        else
//        {
//            m_somevalue+=val;
//            return *this;
//        }
//    }
 
    template<typename U>
    foo & operator +=(foo<U> const& rhs) {   // foo += foo
       m_somevalue += rhs.get();
       return *this;
    }
 
    template<typename U>
    foo & operator +=(U const& rhs) {        // foo += !foo
       m_somevalue += rhs;
       return *this;
    }
};
 
 
int main()
{
    foo<int> a, b;
    foo<long> d;
    a.show();       //10
    b.show();       //10
    d.show();       //10
    (a+=b).show();
    (a+=d).show();
    (a+=5).show();
 
    // system("pause");
    return 0;
}
Добавлено через 18 минут
Возможно ещё так:
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
#include <iostream>
#include <type_traits>
#include <complex>
 
 
template<typename T>
class foo
{
    T m_somevalue;
public:
    foo() : m_somevalue(10) {}
    T get() const {return m_somevalue;}
    void show() const {std::cout<<m_somevalue<<std::endl;}
 
 
    template<typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
    foo & operator +=(foo<U> const& rhs) {   // foo += foo
       m_somevalue += rhs.get();
       return *this;
    }
 
    template<typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
    foo & operator +=(U const& rhs) {        // foo += !foo
       m_somevalue += rhs;
       return *this;
    }
};
 
 
int main()
{
    foo<int> a, b;
    foo<long> d;
    a.show();       //10
    b.show();       //10
    d.show();       //10
    (a+=b).show();
    (a+=d).show();
    (a+=5).show();
 
    // (a += foo<std::complex<float>>()).show();
    // (a += std::complex<float>(5., 0.)).show();
 
    // system("pause");
    return 0;
}
0
DiffEreD
1431 / 768 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
06.12.2012, 22:34  [ТС] #3
Замучился уже с этими шаблонами. Нужен совет. Сделал еще серию перегруженных операторов + и += и застрял на выносе их за пределы класса. Вернее, проблема возникает только с дружественной функцией, если определять ее в классе, то все в порядке. Кто подскажет как ее определить за пределами класса?
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
#include <iostream>
 
template<typename T>
class foo
{
    T m_somevalue;
public:
    foo() : m_somevalue(10) {}
    T get() const {return m_somevalue;}
    void show() const {std::cout<<m_somevalue<<std::endl;}
 
    template<typename U>
    foo & operator +=(foo<U> const& rhs);                          // foo += foo
 
    template<typename U>
    foo & operator +=(U const& rhs);                               // foo += !foo
 
    template<typename U>
    foo operator +(foo<U> const& rhs);                             // foo + foo}
 
    template<typename U>
    foo operator +(U const& rhs);                                  // foo + !foo
 
    template<typename U>     //ЕСЛИ ОПРЕДЕЛИТЬ СДЕСЬ, ТО ВСЕ ВПОРЯДКЕ
    friend foo operator +(U const& lhs, foo const& rhs);            // !foo + foo
};
 
template<typename T> template<typename U>
foo<T>& foo<T>::operator +=(foo<U> const& rhs) {   // foo += foo
    m_somevalue += rhs.get();
    return *this;
}
 
template<typename T> template<typename U>
foo<T>& foo<T>::operator +=(U const& rhs) {        // foo += !foo
    m_somevalue += rhs;
    return *this;
}
 
 
template<typename T> template<typename U>
foo<T> foo<T>::operator +(foo<U> const& rhs) {   // foo + foo
    foo<T> temp(*this);
    temp += rhs;
    return temp;
}
 
template<typename T> template<typename U>
foo<T> foo<T>::operator +(U const& rhs) {        // foo + !foo
    foo<T> temp(*this);
    temp.m_somevalue += rhs;
    return temp;
}
 
template<typename T> template<typename U>   //ВОТ ТУТ  ПРОБЛЕМА
foo<T> operator +(U const& lhs, foo<T> const& rhs) {        // !foo + foo
    foo<T> temp(rhs);
    temp.m_somevalue += lhs;
    return temp;
}
 
int main()
{
    foo<int> a, b;
    foo<double> d;
    double doub = 10.2;
    a.show();       //10
    b.show();       //10
    d.show();       //10
    (a+=b).show();  //OK
    (a+=d).show();  //OK
    (a+=5).show();  //OK
    (a+b).show();   //OK
    (a+d).show();   //OK
    (a+10).show();  //OK
    //(10.2+d+15).show();
    //(doub+d+doub+a).show();
 
    system("pause");
    return 0;
}
0
gray_fox
What a waste!
1522 / 1227 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
06.12.2012, 22:44 #4
Вроде так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template<typename T>
class foo {
   
   // ...
 
   template<typename V, typename U>
   friend foo<V> operator +(U const& lhs, foo<V> const& rhs);
 
   //..
};
 
// ...
 
template<typename V, typename U>
foo<V> operator +(U const& lhs, foo<V> const& rhs) {
   // ...
}
Добавлено через 1 минуту
И кстати, зачем её делать другом? Может просто:
C++
1
2
3
4
5
template<typename V, typename U>
foo<V> operator +(U const& lhs, foo<V> rhs) {
   rhs += lhs;
   return rhs;
}
0
DiffEreD
1431 / 768 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
06.12.2012, 23:22  [ТС] #5
gray_fox, реально помог.

Добавлено через 11 минут
C++
1
2
3
4
5
template<typename V, typename U>
foo<V> operator +(U const& lhs, foo<V> rhs) {
   rhs += lhs;
   return rhs;
}
Вот этот вариант тоже неплох, но аргумент передается по значению, а не по ссылке, так что я остановлюсь на предыдущем.
0
gray_fox
What a waste!
1522 / 1227 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
06.12.2012, 23:53 #6
yuron_477, так какая разница по сравнению с этим, например? Та же копия (temp), только ты её сам создаёшь внутри ф-ии:
Цитата Сообщение от yuron_477 Посмотреть сообщение
C++
1
2
3
4
5
6
template<typename T> template<typename U> //ВОТ ТУТ ПРОБЛЕМА
foo<T> operator +(U const& lhs, foo<T> const& rhs) { // !foo + foo
    foo<T> temp(rhs);
    temp.m_somevalue += lhs;
    return temp;
}
0
06.12.2012, 23:53
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.12.2012, 23:53
Привет! Вот еще темы с ответами:

Перегрузка operator<< для шаблонного класса - C++
Добрый день не могу понять как реализовать перегрузку &lt;&lt; для шаблонного класса template &lt;class T&gt; class List { public: ...

Не работает перегрузка операторов шаблонного класса - C++
помогите кто может разобрать что не работает( в понедельник екзамен, а я так туплю... все ошибки и код прилагаются Error 1 error...

Перегрузка операторов шаблонного класса дружественными функциями - C++
При попытке скомпилировать проект выдаются следующие ошибки: Error 1: error LNK2019: unresolved external symbol &quot;class matrix&lt;int&gt;...

Как корректно передать в метод шаблонного класса объект шаблонного класса в качестве параметра? - C++
header.h template &lt;class T&gt; class MyVector { public: void swap(MyVector&lt;T&gt;Vector); } template &lt;class T&gt; void...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.