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

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

08.12.2012, 13:11. Показов 2145. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru