C ++ зависимый от аргумента шаблона аргумент decltype в искаженном имени ABI

Рассмотрим следующую функцию:

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_
(Ака: decltype (({parm#1}<{parm#2})?((forward<int>)({parm#1})) : ((forward<int>)({parm#2}))) Min<int, int>(int&&, int&&)). Другими словами, выражение, используемое для вывода возвращаемого типа, является частью искаженного имени. Лично я ожидал чего-то более вменяемого _Z3MinIiiET_OS0_OT0_ (Ака: int Min<int, int>(int&&, int&&)). Почему это не так?


Кажется, что G ++ только ставит decltype выражение в тех случаях, когда это действительно необходимо, так как эти формы _Z3Maxii:

  • auto Max(int x, int y) -> int
  • auto Max(int x, int y) -> decltype(0)

12

Решение

Если вы перегружаете шаблоны функций, функции, создаваемые этими шаблонами функций (так называемая специализация шаблонов функций), должны отличаться. Следовательно, Стандарт C ++ указывает, что сигнатура специализаций шаблона функции включает в себя сигнатуру шаблона функции, из которой была создана специализация.

В противном случае, если оба шаблона будут создавать функции с одинаковым типом функции, они будут конфликтовать.

2

Другие решения

GCC использует «Italium C ++ ABI» для каландрирования, и это указывает на то, что

Если выражение операнда decltype не является Инстанциация-зависимой затем результирующий тип кодируется напрямую. Например:

      int x;
template<class T> auto f(T p)->decltype(x);
// The return type in the mangling of the template signature
// is encoded as "i".
template<class T> auto f(T p)->decltype(p);
// The return type in the mangling of the template signature
// is encoded as "Dtfp_E".
void g(int);
template<class T> auto f(T p)->decltype(g(p));
// The return type in the mangling of the template signature
// is encoded as "DTcl1gfp_E".

Третий пример — сокращенная версия OP, которые также кодируют все выражение напрямую, потому что оно зависит от экземпляра. Конкретизация-зависимый определяется как:

Выражение Инстанциация-зависимой если он зависит от типа или значения, или имеет подвыражение, которое зависит от типа или значения. Например, если p типозависимый идентификатор, выражение sizeof(sizeof(p)) не зависит ни от типа, ни от значения, но зависит от экземпляра (и может оказаться недействительным, если после подстановки аргументов шаблона p оказывается неполного типа). Точно так же тип, выраженный в исходном коде, зависит от экземпляра, если исходная форма включает Инстанциация-зависимой выражение. Например, тип формы double[sizeof(sizeof(p))]p зависимый от типа идентификатор) Инстанциация-зависимой.

Ключевым моментом является то, что зависящие от экземпляра выражения «могут оказаться недействительными после подстановки», что, вероятно, является причиной того, что они остаются в неоцененной форме в календаре.

4

По вопросам рекламы [email protected]