Подтвердить что ты не робот

В Itanium С++ 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?

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

4b9b3361

Ответ 1

Проблема возникает из конструкции <unresolved-name> в ABI. Зачем нам когда-либо хотеть использовать неразрешенное имя? Все о согласовании и перегрузках. С++ 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.