Рассмотрим следующую функцию:
template <typename A, typename B>
auto Min(A&& a, B&& b)
-> decltype(a < b ? std::forward<A>(a) : std::forward<B>(b))
{
return a < b ? std::forward<A>(a) : std::forward<B>(b);
}
Фрагмент Min(0, 1) вызывает создание шаблона как Min<int, int>. Как ни странно, искомое имя для Min с g++ и clang для моего кода - _Z3MinIiiEDTqultfp_fp0_cl7forwardIT_Efp_Ecl7forwardIT0_Efp0_EEOS0_OS1_
(aka: decltype (({parm#1}<{parm#2})?((forward<int>)({parm#1})) : ((forward<int>)({parm#2}))) Min<int, int>(int&&, int&&)). Другими словами, выражение, используемое для вывода возвращаемого типа, является частью искаженного имени. Лично я ожидал чего-то чуть более разумного по строкам: _Z3MinIiiET_OS0_OT0_ (aka: int Min<int, int>(int&&, int&&)). Почему это не так?
Похоже, что g++ только выражает выражение decltype в тех случаях, когда это действительно необходимо, так как эти формы являются _Z3Maxii:
-
auto Max(int x, int y) -> int -
auto Max(int x, int y) -> decltype(0)