Например:
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>
предложение мертв в воде.
Вопрос исходит от <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
,
Других решений пока нет …