22

例如:

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++17std::default_order<T>提案在水中死气沉沉的原因。

4

1 回答 1

9

问题来自<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's parade 下雨,问题在于模板 ID 隐式地从模板中提取默认参数。因此,用户可能会无意中在签名中包含依赖类型名,只需提及std::set.

于 2016-10-20T16:07:08.247 回答