c++ templates name-mangling itanium-abi

En el ABI de Itanium C++, ¿por qué el nombre mutilado de las funciones de plantilla no resuelve las definiciones de tipo dependientes?



templates name-mangling (1)

El problema proviene de la construcción <unresolved-name> en el ABI. ¿Por qué querríamos usar un nombre sin resolver? Es todo sobre la coincidencia de declaración y sobrecargas. C ++ 14 §14.5.6.1 / 3 notas,

Dos plantillas de función distintas pueden tener tipos de retorno de función idénticos y listas de parámetros de función, incluso si la resolución de sobrecarga sola no puede distinguirlos.

Puedes tener otra función en un archivo diferente,

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

Aunque esta firma no puede coexistir pacíficamente en el mismo archivo (no se puede nombrar debido a la ambigüedad de la sobrecarga), puede existir en un archivo diferente, por lo que necesita una mutilación distinta.

(Incluso este nivel de coexistencia no está garantizado por el estándar para todas las plantillas. Es una cuestión de QOI que el compilador use la forma exacta de una declaración de plantilla de función para realizar la coincidencia de declaración, por lo que tenderá a copiar y pegar una declaración en una definición para proporcionar una coincidencia exacta y no un conflicto sorprendente con otra plantilla de función que se resuelva con la misma firma. Consulte §14.5.6.1 / 5-6.)

En cuanto a la lluvia en el desfile de default_order , el problema es que los identificadores de plantilla extraen implícitamente los argumentos predeterminados de las plantillas. Por lo tanto, el usuario podría tener involuntariamente un nombre de tipo dependiente en una firma con solo mencionar std::set .

Por ejemplo:

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);

¿Por qué la forma mutilada de baz<int> menciona a foo ? ¿Cómo es que no es _Z3bazIiEvi ?

Aparentemente, esta es la razón por la que la propuesta de C ++ 17 std::default_order<T> está muerta en el agua.