在Itanium c++ ABI中,为什么模板函数的混乱名称不能解析依赖类型?
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注释,
两个不同的函数模板可以有相同的函数返回类型和函数形参表,即使单独的重载解析不能区分它们。
你可以在另一个文件中有另一个函数,
template <typename T>
void baz(int quux) { std::abort(); }
尽管这个签名不能和平地共存于同一个文件中——由于重载的模糊性,它不能被命名——但它可以存在于不同的文件中,所以它需要一个不同的mangling
(即使这种共存级别也不是所有模板的标准所保证的。编译器使用函数模板声明的确切形式来执行声明匹配是一个QOI问题,因此将声明复制粘贴到定义中将倾向于提供精确匹配,而不会与解析到相同签名的另一个函数模板发生意外冲突。看到§14.5.6.1/5-6。)
至于default_order
的队列,问题是模板id隐式地从模板中提取默认参数。因此,用户可能仅仅通过提到std::set
就无意中在签名中拥有一个依赖的类型名。
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我的for循环不能正确获取argv
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 为什么我不能在 FOR LOOP 中使用 i/10,C++?
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 为什么模板类中的对象不能返回值
- 为什么我不能在一个类的不同行中声明和定义成员变量?
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- ld:bind_at_load和-bitcode_bundle(Xcode设置ENABLE_bitcode=YES)不能
- 数组长度,为什么从命令行获取时不能使用它?
- Windows/Cygwin - 不能使用 pybind11 - 犯错误
- 为什么我不能使用 EGL 创建无头 OpenGl 上下文?
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么我不能将一个对象push_back到属于另一个类的对象向量中?
- 为什么我不能将 rand() 与数组的大小一起使用?
- 为什么虚函数不能是静态的和全局的?
- 为什么我不能在 while 循环中创建线程?
- 为什么这个音频包络不能通过开关的情况?
- 在Itanium c++ ABI中,为什么模板函数的混乱名称不能解析依赖类型?