Using - это сильный typedef или такой как и раньше?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 26.05.22 17:08
Оценка:
Здравствуйте!

namespace my_ns
{

template < typename T >
using Opt = std::optional<T>;


using json_scalar = 
std::variant< bool             // std::get<0>(...)
            , std::int64_t     // std::get<1>(...)
            , std::uint64_t    // std::get<2>(...)
            , double           // std::get<3>(...)
            , std::string      // std::get<4>(...)
            , ArrayText        // std::get<5>(...)
            , ObjectText       // std::get<6>(...)
            >
            ; // json_scalar;


} // namespace my_ns


и например, в другом namespace сделаем аналогичное — будут ли типы одинаковыми с точки зрения компилятора?

ЗЫ И в догонку — enum class насколько строг?
Маньяк Робокряк колесит по городу
Re: Using - это сильный typedef или такой как и раньше?
От: σ  
Дата: 26.05.22 18:00
Оценка:
M>и например, в другом namespace сделаем аналогичное — будут ли типы одинаковыми с точки зрения компилятора?
А проверить?

M>ЗЫ И в догонку — enum class насколько строг?

Как мая матиматичка.
Отредактировано 26.05.2022 18:17 σ . Предыдущая версия . Еще …
Отредактировано 26.05.2022 18:16 σ . Предыдущая версия .
Re[2]: Using - это сильный typedef или такой как и раньше?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 26.05.22 18:02
Оценка: :)
Здравствуйте, σ, Вы писали:

M>>и например, в другом namespace сделаем аналогичное — будут ли типы одинаковыми с точки зрения компилятора?

σ>А проверить?

Проверить конечно можно, но: а) не факт, что я проверю именно то, что в итоге получится в рабочем проекте; б) думал нахаляву ответ получить
Маньяк Робокряк колесит по городу
Re[2]: Using - это сильный typedef или такой как и раньше?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 26.05.22 20:34
Оценка:
Здравствуйте, σ, Вы писали:

M>>ЗЫ И в догонку — enum class насколько строг?

σ>Как мая матиматичка.

Кстати, это не аргумент. Может, она к тебе в постели была ещё строже, чем на уроках
Маньяк Робокряк колесит по городу
Re: Using - это сильный typedef или такой как и раньше?
От: Андрей Тарасевич Беларусь  
Дата: 27.05.22 06:45
Оценка: 4 (1)
Здравствуйте, Marty, Вы писали:

M>...


Такой же, как раньше. То есть в таких примерах различия чисто косметические.

Некосметические различия проявляются при использовании `using` в "template typedef", где он работает логичнее, чем классическая идиома со `struct`.
Best regards,
Андрей Тарасевич
Re: Using - это сильный typedef или такой как и раньше?
От: sergii.p  
Дата: 27.05.22 06:57
Оценка: 4 (1)
Здравствуйте, Marty, Вы писали:

M>и например, в другом namespace сделаем аналогичное — будут ли типы одинаковыми с точки зрения компилятора?


is_same выдаст true. Типы будут одинаковы. Потому как собственно новый тип не создаётся.


M>ЗЫ И в догонку — enum class насколько строг?


для создания нового типа подходит. Убирает проблемы перепутанных параметров в функцию почти полностью.
Re[2]: Using - это сильный typedef или такой как и раньше?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 27.05.22 15:40
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Такой же, как раньше. То есть в таких примерах различия чисто косметические.


Спс


АТ>Некосметические различия проявляются при использовании `using` в "template typedef", где он работает логичнее, чем классическая идиома со `struct`.


А вот тут не понял, можно мысль раскрыть?
Маньяк Робокряк колесит по городу
Re: Using - это сильный typedef или такой как и раньше?
От: rg45 СССР  
Дата: 27.05.22 19:37
Оценка: 4 (1)
Здравствуйте, Marty, Вы писали:

M>и например, в другом namespace сделаем аналогичное — будут ли типы одинаковыми с точки зрения компилятора?


Не просто одинаковыми, а идентичными Т.е. это просто один и тот же тип.

Я даже больше скажу, при вызове функции без использования явной квалификации пространства имен, активируется ADL (Argument Dependent Lookup). Так вот, ADL будет искать кандидата на подстановку в том пространстве имен, где определен реальный тип (в случае UDT), а в пространство имен, где определен алиас, даже не заглянет. Это такие грабли, про которые многие постоянно забывают, почему-то. Ниже иллюстрация:

http://coliru.stacked-crooked.com/a/e3c84cee78545253

#include <iostream>

namespace ns1 {

struct A {};

void foo(const A&) { std::cout << 1 << std::endl; }

}

namespace ns2 {

using B = ns1::A;

void foo(const B&) { std::cout << 2 << std::endl; }

}


int main()
{
    const ns1::A a;
    const ns2::B b;

    foo(a); // --> 1
    foo(b); // --> 1 again, not 2!
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 27.05.2022 20:12 rg45 . Предыдущая версия .
Re[3]: Using - это сильный typedef или такой как и раньше?
От: ArtDenis Россия  
Дата: 28.05.22 03:00
Оценка:
Здравствуйте, Marty, Вы писали:

M>А вот тут не понял, можно мысль раскрыть?


template<typename T>
using IntKeyMap = std::map<int, T>;
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[3]: Using - это сильный typedef или такой как и раньше?
От: rg45 СССР  
Дата: 28.05.22 08:21
Оценка: 4 (1)
Здравствуйте, Marty, Вы писали:

АТ>>Некосметические различия проявляются при использовании `using` в "template typedef", где он работает логичнее, чем классическая идиома со `struct`.


Речь идет о задаче, когда из набора каких-то типов и/или констант требуется вывести новый тип. Например, из списка типов формальных параметров вывести сигнатуру функции. Или наоборот, имея сигнатуру функции, получить тип возвращаемого значения... Круг задач чрезвычайно широк. До появления шаблонного варианта using-declaration, эта задача традиционно решалась через объявление шаблонного класса (структуры), и определения вложенного алиаса типа. Потом для доступа к этому вложенному алиасу нужно было указать имя шаблонного класса, фактические параметры шаблона и, наконец, имя самого алиаса через двойное двоеточие. Да, и, как правило, нужно было еще не забыть указать перед всей этой конструкцией ключевое слово typename, в случаях использования врутри других шаблонов. В результате получались довольно громоздкие конструкции, которые существенно загромождали код. Шаблонный вариант using-declaration позволяет сократить такие конструкции до имени с набором шаблонных параметров в угловых скобочках. Но я бы не сказал, что шаблонный using-declaration полностью вытесняет старый подход с шаблонным классом, поскольку, при написании шаблонных метафункций, как правило, требуются специализации, а using-declaration специализации не поддерживает. Поэтому стандартный подход таков: сначала определяем шаблонный класс со всеми необходимыми специализациями и предоставляем к этому набору удобную в использовании обертку в виде using-declaration. Такой подход активно используется в стандартной библиотеке — можно видеть, что большинство шаблонных метафункций-классов имеют пару в виде алиаса с суффиксом '_t': is_same — is_same_t, decay — decay_t, remove_reference — remove_reference_t и т.п.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: Using - это сильный typedef или такой как и раньше?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 28.05.22 12:09
Оценка:
Здравствуйте, ArtDenis, Вы писали:

M>>А вот тут не понял, можно мысль раскрыть?


AD>
AD>template<typename T>
AD>using IntKeyMap = std::map<int, T>;
AD>


А где тут некосметические отличия? То же ж type alias, не?
Маньяк Робокряк колесит по городу
Re[5]: Using - это сильный typedef или такой как и раньше?
От: ArtDenis Россия  
Дата: 28.05.22 13:50
Оценка:
Здравствуйте, Marty, Вы писали:

M>А где тут некосметические отличия? То же ж type alias, не?


Но возможно я его неправильно понял Андрея Тарасевича
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[3]: Using - это сильный typedef или такой как и раньше?
От: Андрей Тарасевич Беларусь  
Дата: 28.05.22 23:59
Оценка:
Здравствуйте, Marty, Вы писали:

АТ>>Некосметические различия проявляются при использовании `using` в "template typedef", где он работает логичнее, чем классическая идиома со `struct`.


M>А вот тут не понял, можно мысль раскрыть?


До того, как в языке повился `using` и, соответственно, возможность использовать его для "template typedef", последний более-менее реализовывался через идиоматический прием со struct:

template <class T> struct MapToInt
{
  typedef typename std::map<T, int> type;
};


Однако в таком варинате получившийся производный тип, при использовании в параметрах шаблонных функций, оказывался в non-deduced context

template <class T> void foo(typename MapToInt<T>::type &m) {}

int main()
{
  MapToInt<int>::type m;
  foo(m);
}


main.cpp: In function 'int main()':
main.cpp:15:6: error: no matching function for call to 'foo(MapToInt<int>::type&)'
   15 |   foo(m);
      |   ~~~^~~
main.cpp:8:25: note: candidate: 'template<class T> void foo(typename MapToInt<T>::type&)'
    8 | template <class T> void foo(typename MapToInt<T>::type &m)
      |                         ^~~
main.cpp:8:25: note:   template argument deduction/substitution failed:
main.cpp:15:6: note:   couldn't deduce template parameter 'T'
   15 |   foo(m);
      |   ~~~^~~


А если теперь перейти к использованию template typedef на основе `using`, то все сразу заработает, так как свозь него работает дедукция.
Best regards,
Андрей Тарасевич
Отредактировано 29.05.2022 16:22 Андрей Тарасевич . Предыдущая версия . Еще …
Отредактировано 29.05.2022 8:17 Андрей Тарасевич . Предыдущая версия .
Re[4]: Using - это сильный typedef или такой как и раньше?
От: ArtDenis Россия  
Дата: 29.05.22 04:48
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>До того, как в языке повился `using` и, соответственно, возможность использовать его для "template typedef", последний более-меннеереализовывался через идиоматический прием со struct:


При наследовании у компилятора всё получается )
template <class T> 
struct MapToInt: std::map<T, int> {};

template <class T> 
void foo(const MapToInt<T> &m) 
{
    // blabla    
}
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[5]: Using - это сильный typedef или такой как и раньше?
От: Андрей Тарасевич Беларусь  
Дата: 29.05.22 08:20
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>Здравствуйте, Андрей Тарасевич, Вы писали:


АТ>>До того, как в языке повился `using` и, соответственно, возможность использовать его для "template typedef", последний более-меннеереализовывался через идиоматический прием со struct:


AD>При наследовании у компилятора всё получается )

AD>
AD>template <class T> 
AD>struct MapToInt: std::map<T, int> {};

AD>template <class T> 
AD>void foo(const MapToInt<T> &m) 
AD>{
AD>    // blabla    
AD>}
AD>


Это свой комок проблем. Когда речь идет о typedef во всех его проявлениях, я все таки хочу классический typedef, то есть псевдоним, а не новый тип. Я хочу, чтобы `MapToInt<int>` было тем же типом, что и `std::map<int, int>`.
Best regards,
Андрей Тарасевич
Re[6]: Using - это сильный typedef или такой как и раньше?
От: ArtDenis Россия  
Дата: 29.05.22 09:35
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Это свой комок проблем. Когда речь идет о typedef во всех его проявлениях, я все таки хочу классический typedef, то есть псевдоним, а не новый тип. Я хочу, чтобы `MapToInt<int>` было тем же типом, что и `std::map<int, int>`.


Всё верно. Но в те времена, лично для меня достаточно было "лишь бы компилировалось и работало как надо"
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[7]: Using - это сильный typedef или такой как и раньше?
От: rg45 СССР  
Дата: 29.05.22 18:21
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>Всё верно. Но в те времена, лично для меня достаточно было "лишь бы компилировалось и работало как надо"


С наследованием тоже есть свои нюансы. Во-первых, не от всякого типа можно наследоваться. Во-вторых, когда в системе используются какие-то утилиты общего применения (форматирование, сериализация и пр.), они могут перестать работать, потому что вместо ожидаемой перегрузки для std::map начинает подхватываться более общий шаблонный вариант. Да, можно предоставить дополнительные перегрузки, можно подправить существующий набор перегрузок, сделать их более "умными". Но все это дополнительные телодвижения, дополнительное тестирование, которых могло бы не быть.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 30.05.2022 7:21 rg45 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.