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

C++

Войти
Регистрация
Восстановить пароль
 
Archi0
28 / 14 / 4
Регистрация: 18.07.2013
Сообщений: 167
#1

Объясните принцип шаблона Common_type - C++

14.11.2016, 17:35. Просмотров 277. Ответов 4
Метки нет (Все метки)

Читал шаблоны из распространённых библиотек и наткнулся на
C++
1
2
3
4
5
6
7
8
9
10
template<class _Ty0,
    class _Ty1>
    struct common_type<_Ty0, _Ty1>
    {   // type is common type of _Ty0 and _Ty1 for two arguments
    typedef typename decay<
        decltype(_Always_false<_Ty0>::value
            ? _STD declval<_Ty0>()
            : _STD declval<_Ty1>())
    >::type type;
    };
и понять не могу разве это не равно
C++
1
typedef typename decay<_Ty1>::type type;
В чем сакральный смысл был городить многоэтажную конструкцию выше?
C++
1
2
3
(_Always_false<_Ty0>::value
            ? _STD declval<_Ty0>()
            : _STD declval<_Ty1>()
всегда
C++
1
_STD declval<_Ty1>()
вешает правую ссылку
C++
1
2
3
template<class _Ty>
    typename add_rvalue_reference<_Ty>::type
        declval() _NOEXCEPT;
то есть
C++
1
2
3
decltype(_Always_false<_Ty0>::value
            ? _STD declval<_Ty0>()
            : _STD declval<_Ty1>())
равен
C++
1
add_rvalue_reference<_Ty1>::type
и не может вызвать ошибок компиляции потому что в этом шаблоне стоит условный оператор который просто не вешает ссылку на то, что не допускает добавить ссылку.
Но
C++
1
decay<add_rvalue_reference<_Ty1>::type>
на первом этапе убирает ссылку так, что равен просто
C++
1
typedef typename decay<_Ty1>::type type;
В итоге дополнительные этапы и ошибок не могут вызвать и сокращены могут до более простой записи.
Для чего тогда была записана длинная версия?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.11.2016, 17:35     Объясните принцип шаблона Common_type
Посмотрите здесь:

Возвращаемый тип шаблона через std::common_type - C++
Вот отрывок моего кода. Не могу понять как определить возвращаемый тип объекта matrix. template&lt;typename V, typename U, size_t R, size_t...

Объясните принцип - C++
printf(&quot;%.2lf&quot;, x) Объясните пожалуйста понятным языком, что делает эта вещь &quot;%.2lf&quot;?

Принцип инициализации статических членов шаблона класса - C++
Доброго времени суток. Рассмотрим пример: #include &lt;iostream&gt; int foo(){ return 0; } template&lt;class T&gt; struct...

Объясните принцип работы программы - C++ Builder
доброго времени суток написал программу, она создает массив из чисел которые берет из edit1 и edit2 и затем массив выводит в edit3,...

объясните принцип работы цикла : ? - C++
объясните принцип работы цикла : ?

Объясните, пожалуйста, принцип работы. - C++
Есть прога, считает сумму ряда, но ряд - знакочередующийся (-1,1,-1,...). При подсчете программа заканчивае работу на 1023 члене. Но чем...

Объясните принцип работы программы - C++
Добрый день ( вечер ). Мне дано было задание: Определить класс, объектами которого являются многоугольники указанного типа. ...

Объясните принцип работы программы - C++
//--------------------------------------------------------------------------- #include &lt;vcl.h&gt; #pragma hdrstop #include &lt;conio.h&gt; ...

Объясните принцип создания многопоточности - C++
Здраствуйте, объясните пожалйста как сделать программу многопоточной, у меня есть одна программа, в которой большая нагрузка идет на...

Объясните принцип бинарного поиска - C++
Можно, пожалуйста, пример или принцип бинарного поиска. С++ для очень сильно начинающих.

ввод/вывод.Объясните принцип. - C++ Builder
Программа реализации модели ввода/вывода в режиме с опросом готовности. Как это понять?Примерно какую прогу надо написать?

Односвязные списки. Объясните принцип работы. - C++
обьясните плзз как раотает односвязный список


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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6909 / 4102 / 933
Регистрация: 30.01.2014
Сообщений: 6,893
14.11.2016, 20:49     Объясните принцип шаблона Common_type #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Archi0, у тебя шаблон как называется?
Правильно - common_type.
Это значит, что выбирается общий тип между двумя переданными. Поэтому твое предположение про использование только _Ty1 сломает логику, это уже чисто на интуиции должно было сработать

Само условие "всегда false" нужно для того, чтобы condition expression ?: вывел нам из двух своих операндов общий тип. Condition expression использует стандартные преобразования (арифметические преобразования, преобразования указателей и др., см. в стандарте детали), если типы различаются. И это не всегда будет один из типов операндов. Например, для выражения decltype(false ? short(1) : char(2)) выведен будет int.
Archi0
28 / 14 / 4
Регистрация: 18.07.2013
Сообщений: 167
15.11.2016, 04:44  [ТС]     Объясните принцип шаблона Common_type #3
В чем отличие от
C++
1
decltype(_Always_false<_Ty0>::value ? _Ty0: _Ty1>)
Для чего используются правые ссылки?
DrOffset
6909 / 4102 / 933
Регистрация: 30.01.2014
Сообщений: 6,893
15.11.2016, 09:05     Объясните принцип шаблона Common_type #4
Цитата Сообщение от Archi0 Посмотреть сообщение
В чем отличие от
Во-первых так нельзя. Не скомпилируется. Операндами должны быть объекты. Т.е. так:
C++
1
decltype(_Always_false<_Ty0>::value ? _Ty0() : _Ty1()>)
Хоть на самом деле ни один из объектов не будет создан, но все требования к типам, которые накладывает такая запись, должны быть соблюдены. В частности, эта запись требует наличия конструктора без параметров. Не все типы могут предоставить такой конструктор. Поэтому для получения объекта в выражении используется declval().

Цитата Сообщение от Archi0 Посмотреть сообщение
Для чего используются правые ссылки?
Предположим, что declval() у нас реализован так:
C++
1
2
template <typename T>
T declval();
Если мы используем его с типом, например, int[2], то будет ошибка компиляции, т.к. массивы нельзя возвращать по значению. Также, аргументом шаблона могут быть типы с отсутствующим (удаленным или помещенным в private) конструктором копирования, и это тоже приведет к ошибке компиляции в случае использования такого declval(). Поэтому используется ссылка. Например, благодаря этому, можно вывести общий тип для двух массивов:
C++
1
common_type<int[3], int[4]>::type; // -> int *
Archi0
28 / 14 / 4
Регистрация: 18.07.2013
Сообщений: 167
15.11.2016, 15:47  [ТС]     Объясните принцип шаблона Common_type #5
Дополнение к работе ?:, чтобы тема была полностью раскрыта.
попробовал код снизу
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
class C
{};
 
class A
{
public:
    operator C() const
    {
        return C();
    }
};
 
class B
{
public:
    operator C() const
    {
        return C();
    }
    /*
    operator A() const
    {
        return A();
    }
    */
};
 
template <>
struct std::common_type<A, B>
{
    typedef C type;
};
 
int main()
{
    std::common_type<A, B>::type w;
    class C c = w;
Если убрать явную специализацию шаблона, то будет ошибка B не может быть преобразована в A.
Yandex
Объявления
15.11.2016, 15:47     Объясните принцип шаблона Common_type
Ответ Создать тему
Опции темы

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