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

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

Восстановить пароль Регистрация
 
Archi0
28 / 14 / 4
Регистрация: 18.07.2013
Сообщений: 164
14.11.2016, 17:35     Объясните принцип шаблона Common_type #1
Читал шаблоны из распространённых библиотек и наткнулся на
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
Посмотрите здесь:

объясните принцип работы цикла : ? C++
C++ Объясните, пожалуйста, принцип работы.
C++ Возвращаемый тип шаблона через std::common_type
Принцип инициализации статических членов шаблона класса C++
Объясните принцип C++
C++ Объясните принцип работы программы
Объясните принцип работы программы C++
C++ Объясните принцип бинарного поиска

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6416 / 3790 / 876
Регистрация: 30.01.2014
Сообщений: 6,575
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
Сообщений: 164
15.11.2016, 04:44  [ТС]     Объясните принцип шаблона Common_type #3
В чем отличие от
C++
1
decltype(_Always_false<_Ty0>::value ? _Ty0: _Ty1>)
Для чего используются правые ссылки?
DrOffset
6416 / 3790 / 876
Регистрация: 30.01.2014
Сообщений: 6,575
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
Сообщений: 164
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
Ответ Создать тему
Опции темы

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