Информация об изменениях

Сообщение Re[3]: Using - это сильный typedef или такой как и раньше? от 28.05.2022 23:59

Изменено 29.05.2022 16:22 Андрей Тарасевич

Re[3]: Using - это сильный typedef или такой как и раньше?
Здравствуйте, 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`, то все сразу заработает, так как свозь него работает дедукция.
Re[3]: Using - это сильный typedef или такой как и раньше?
Здравствуйте, 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`, то все сразу заработает, так как свозь него работает дедукция.