在 Itanium C++ ABI 中,为什么模板函数的错位名称不能解析相关的 typedef?

In the Itanium C++ ABI, why does the mangled name for template functions not resolve dependent 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> 提案搁浅的原因。

问题来自 ABI 中的 <unresolved-name> 构造。为什么我们要使用未解析的名称?这都是关于声明匹配和重载的。 C++14 §14.5.6.1/3 注释,

Two distinct function templates may have identical function return types and function parameter lists, even if overload resolution alone cannot distinguish them.

你可以在不同的文件中有另一个函数,

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

虽然这个签名不能在同一个文件中和平共存——由于重载歧义,它不能被命名——但它可以存在于不同的文件中,所以它需要一个不同的修改。

(即使是这种级别的共存也不能保证所有模板的标准。编译器使用函数模板声明的确切形式来执行声明匹配是 QOI 的问题,因此复制粘贴声明到一个定义中将倾向于提供一个精确的匹配,而不是与另一个解析为相同签名的函数模板发生令人惊讶的冲突。参见 §14.5.6.1/5-6。)

至于下雨 default_order 的游行,问题是模板 ID 隐式地从模板中提取默认参数。因此,用户可能无意中通过提及 std::set.

在签名中拥有依赖类型名