在Itanium C++ ABI中,为什么模板函数的受损名称不能解析依赖的typedef?

Tav*_*nes 22 c++ templates name-mangling itanium-abi

例如:

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);
Run Code Online (Sandbox Code Playgroud)

为什么要baz<int>提到破败的形式foo呢?怎么没有_Z3bazIiEvi

这显然是C++ 17 std::default_order<T>提案在水中死亡的原因.

Pot*_*ter 8

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

两个不同的函数模板可能具有相同的函数返回类型和函数参数列表,即使单独的重载分辨率无法区分它们.

你可以在另一个文件中有另一个功能,

template <typename T>
void baz(int quux) { std::abort(); }
Run Code Online (Sandbox Code Playgroud)

虽然这个签名不能在同一个文件中和平共存 - 由于过载歧义而无法命名 - 它可以存在于不同的文件中,因此需要进行明显的修改.

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

至于下雨default_order的游行,问题是template-ids隐含地从模板中提取默认参数.因此,用户可能只是通过提及无意中在签名中具有依赖类型名称std::set.