В Itanium C++ ABI, почему искаженное имя для функций шаблона не разрешает зависимые typedefs?

например:

template <typename T>
struct foo
{
    using bar = int;
};

// _Z3bazi
void baz(foo<int>::bar quux) {
}

template <typename T>
void baz(typename foo<T>::bar quux) {
}

// _Z3bazIiEvN3fooIT_E3barE
template void baz<int>(foo<int>::bar quux);

почему искалеченная форма baz<int> отметить foo на всех? Почему это не _Z3bazIiEvi?

это, по-видимому, причина того, что C++17 std::default_order<T> предложение мертво в воде.

1 ответов


проблема исходит от <unresolved-name> построить в ABI. Зачем нам вообще использовать неразрешенное имя? Все дело в сопоставлении деклараций и перегрузках. C++14 §14.5.6.1 / 3 примечания,

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

вы можете иметь другую функцию в другом файле,

template <typename T>
void baz(int quux) { std::abort(); }

хотя эта подпись не может мирно сосуществовать в одном файле - она не может быть названа из - за неоднозначности перегрузки-она может существовать в другом файле, поэтому ей нужно отдельное искажение.

(даже такой уровень сосуществования не гарантируется стандартом для всех шаблонов. Это вопрос QOI, что компилятор использует точную форму объявления шаблона функции для выполнения соответствия объявления, так что копирование-вставка объявления в определение будет иметь тенденцию обеспечивать точное соответствие и неудивительно, что конфликт с другим шаблоном функции, который разрешает ту же подпись. См. §14.5.6.1/5-6.)

что касается дождя на default_orderпарад, проблема в том, что идентификаторы шаблонов неявно извлекают аргументы по умолчанию из шаблонов. Таким образом, пользователь может непреднамеренно иметь зависимое имя типа в подписи, просто упомянув std::set.