С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2

Возвращаемый тип шаблона через std::common_type

08.12.2012, 13:11. Показов 2085. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вот отрывок моего кода. Не могу понять как определить возвращаемый тип объекта matrix.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template<typename V, typename U, size_t R, size_t C>
matrix</*U или V*/,R,C> operator+(const V& value, const matrix<U,R,C>& rhs)                      //!matrix+matrix
{
    std::cout<<"!matrix+matrix\n";
    std::cout<<"common_type<V,U>::type = "<<typeid(std::common_type<V,U>::type).name()<<std::endl;
    if (!std::is_fundamental<V>::value) throw std::logic_error ("Не совместимый тип при операции +\n");
    else
    {
        matrix<std::common_type<V,U>::type,R,C> ret_matrix(rhs);
        ret_matrix+=value;
        return ret_matrix;
    }
}
Такое не проходит:
C++
1
2
template<typename V, typename U, size_t R, size_t C>
matrix<std::common_type<V,U>::type,R,C> operator+(const V& value, const matrix<U,R,C>& rhs) {...}
Через auto тоже не проходит.
Как это правильно сделать?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.12.2012, 13:11
Ответы с готовыми решениями:

Реализация std::common_type
Встретил следующую реализацию std::common_type template &lt;class T, class U&gt; struct common_type&lt;T, U&gt; { typedef decltype(true ?...

Функции, возвращаемый тип
Как сделать так, что бы функция возвращала разный тип данных, в зависимости от некой глобальной переменной? Например, если эта...

Возвращаемый тип по умолчанию
Приветствую всех! В книге Р. Лафоре &quot;Объектно-ориентированное программирование в C++&quot; прочитал следующее: Скажите, с чем...

11
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
08.12.2012, 13:32
Цитата Сообщение от yuron_477 Посмотреть сообщение
std::common_type<V,U>::type
typename std::common_type<V,U>::type.
Это как минимум, т.к. type - зависимый от U и V тип.

Добавлено через 11 минут
Цитата Сообщение от yuron_477 Посмотреть сообщение
if (!std::is_fundamental<V>::value) throw std::logic_error ("Не совместимый тип при операции +\n");
Кстати, вместо
C++
1
if (!std::is_fundamental<V>::value) throw std::logic_error ("Не совместимый тип при операции +\n");
логичнее было бы
C++
1
static_assert(std::is_fundamental<V>::value, "Не совместимый тип при операции +.");
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
08.12.2012, 13:37  [ТС]
static_assert приму к сведению, а вот относительно typename std::common_type<V,U>::type чета я не понял, где его определять?
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
08.12.2012, 13:51
yuron_477, например здесь:
Цитата Сообщение от yuron_477 Посмотреть сообщение
matrix</*U или V*/,R,C>
C++
1
matrix<typename std::common_type<U, V>::type, R, C>
вообщем везде, где использушь std::common_type, и вообще с любыми типами, которые зависят от параметра шаблона, нужен typename. Компилятор не в курсе, что такое type - тип, статический метод или ещё что-нибудь, надо явно это указывать.
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
08.12.2012, 14:14  [ТС]
Да, все заработало. Вообщем, репект и уважуха
Окончательный вариант:
C++
1
2
3
4
5
6
7
8
9
10
template<typename V, typename U, size_t R, size_t C>
matrix<typename std::common_type<U, V>::type,R,C> operator+(const V& value, const matrix<U,R,C>& rhs)                       //!matrix+matrix
{
    //std::cout<<"!matrix+matrix\n";
    //std::cout<<"common_type<V,U>::type = "<<typeid(typename std::common_type<U, V>::type).name()<<std::endl;
    static_assert(std::is_fundamental<V>::value, "Не совместимый тип при операции +.");
    matrix<typename std::common_type<U, V>::type,R,C> ret_matrix(rhs);
    ret_matrix+=value;
    return ret_matrix;
}
Еще, походу, спрошу про static_assert - как его правильно обрабатывать при срабатывании?
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
08.12.2012, 14:22
Цитата Сообщение от yuron_477 Посмотреть сообщение
static_assert - как его правильно обрабатывать при срабатывании?
Всмысле? static_assert - это как assert, только времени компиляции. Если его первый параметр - false, то будет ошибка компиляции с сообщением из его второго параметра. Смысл в том, что std::is_fundamental<V>::value вычисляется на этапе компиляции, и помоему лучше ловить такие штуки во время компиляции вместо времени выполнения (например, бросать исключение, как в твоём примере).
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
08.12.2012, 14:37  [ТС]
Понял, уже разобрался.
0
 Аватар для zarko97
279 / 39 / 13
Регистрация: 11.10.2015
Сообщений: 405
25.12.2016, 19:02
А не проще так было сделать:
C++
1
2
3
4
5
template<class V, class U, size_t R, size_t C>
matrix<typeof(V() + U()),R,C> operator+(const V& value, const matrix<U,R,C>& rhs)
{
     // бла бла бла...
}
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
25.12.2016, 19:06
Цитата Сообщение от zarko97 Посмотреть сообщение
А не проще так было сделать
Нет, потому что тогда код стал бы непереносимым, т.к. никакого typeof в языке с++ по стандарту нет.
0
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
25.12.2016, 19:16
Цитата Сообщение от zarko97 Посмотреть сообщение
А не проще так было сделать
Чисто теоретически, у типа V или U может не быть конструктора по умолчанию.
С другой стороны, не факт, что результат суммирования будет иметь тот же тип, что даст common_type (да, прокси-типы, это я про вас подумал!).
Получается, более корректным вариантом будет такой:
C++
1
matrix<decltype(std::declval<V>() + std::declval<U>()), R, C>
Впрочем, если мы имеем дело с прокси-типами, они и эту малину испортят.
0
 Аватар для zarko97
279 / 39 / 13
Регистрация: 11.10.2015
Сообщений: 405
25.12.2016, 21:38
Очень даже неплохой вариант, наверное, самый рациональный...если с тайпофами мутить то можно как-то так:
C++
1
2
3
4
5
template<class V, class U, size_t R, size_t C>
operator+(const V& value, const matrix<U,R,C>& rhs) -> matrix<typeof(value + rhs),R,C> 
{
     // бла бла бла...
}
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
25.12.2016, 22:32
Цитата Сообщение от DiffEreD Посмотреть сообщение
template<typename V, typename U, size_t R, size_t C>
matrix<std::common_type<V,U>::type,R,C> operator+(const V& value, const matrix<U,R,C>& rhs) {...}
http://rextester.com/PIR37802

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
//========================================================================
//========================================================================
//========================================================================
 
    /* demangle names ot types */
 
#include <typeinfo>
#include <string>
 
#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
 
    #include <cxxabi.h>
    #include <memory>
    
    std::string demangle(const char* name) {
    
        int status = -1; 
        std::unique_ptr<char, void(*)(void*)> res {
            abi::__cxa_demangle(name, NULL, NULL, &status),
            std::free
        };
        return (status == 0) ? res.get() : name ;
    }
#else
 
    std::string demangle(const char* name) 
        { return name; }
 
#endif
 
template <class T> std::string type(const T& t) 
    { return demangle(typeid(t).name()); }
 
 
//========================================================================
//========================================================================
//========================================================================
 
#include <iostream>
 
template<class U, size_t R, size_t C>
struct matrix
{
    matrix(){}
    
    matrix(auto&& rsh)
        { std::cout << type(*this) << " was build!\n"; }
    
    matrix& operator+=(const auto& value) 
        { return *this; }
};
 
template<class V, class U>
    using common_t = 
        typename std::common_type<V,U>::type;
 
template<class V, class U, size_t R, size_t C>
    using matrix_t = 
        matrix< common_t<V,U>,R,C>;
 
 
template<class V, class U, size_t R, size_t C>
matrix_t<V,U,R,C> operator+(const V& value, const matrix<U,R,C>& rhs) 
{
    static_assert(
        std::is_fundamental<V>::value,
        "not compatible type for operator+"
    );
    
    std::cout <<"!matrix+matrix\n";
    
    std::cout << "common_type<V,U>::type = " 
        << type(common_t<V,U>{}) 
        << std::endl;
    
    matrix_t<V,U,R,C> ret_matrix(rhs);
    ret_matrix += value;
    return ret_matrix;
}
 
 
int main()
{
    std::cout << "Hello, world!\n";
    
    matrix<int, 10,20> matrixSample;
    auto result = 10.5 + matrixSample;
    
    std::cout << "type of result is " << type(result)<< std::endl;
    
}
Добавлено через 2 минуты
Цитата Сообщение от gray_fox Посмотреть сообщение
typename std::common_type<V,U>::type.
вместо этого можно использовать:
C++
1
common_type_t<V,U>
Добавлено через 15 секунд
Цитата Сообщение от gray_fox Посмотреть сообщение
typename std::common_type<V,U>::type.
вместо этого можно использовать:
C++
1
common_type_t<V,U>
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.12.2016, 22:32
Помогаю со студенческими работами здесь

Непонятный возвращаемый тип
Расскажите какой тип должен быть у переменной idRe, чтобы можно было бы присвоить ему значение s.length , если s объект класса string?

Перегрузка оператора - возвращаемый тип
class A { private: int x; public: A&amp; operator += (int y); }; A&amp; A::operator += (int y) { x = y; ...

Перегруженные функции. Возвращаемый тип
Добро всем времени суток. Изучаю Р.Лаворе книгу и наткнулся на непонятныий мне аспект. Вот есть код: String(char s) { ...

Объясните принцип шаблона Common_type
Читал шаблоны из распространённых библиотек и наткнулся на template&lt;class _Ty0, class _Ty1&gt; struct common_type&lt;_Ty0,...

Возвращаемый тип как rvalue reference
Нашел интересный пример в книге Мейерса Эффективный и современный С++. class Widget { public: using DataType =...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru