Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在安腾C++;ABI,为什么模板函数的损坏名称不能解析依赖的typedef?_C++_Templates_Name Mangling_Itanium Abi - Fatal编程技术网

C++ 在安腾C++;ABI,为什么模板函数的损坏名称不能解析依赖的typedef?

C++ 在安腾C++;ABI,为什么模板函数的损坏名称不能解析依赖的typedef?,c++,templates,name-mangling,itanium-abi,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&g

例如:

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);
模板
结构foo
{
使用bar=int;
};
//_Z3bazi
void baz(foo::bar qux){
}
模板
void baz(类型名foo::bar qux){
}
//Z3bazIiEvN3fooIT_E3;
模板void baz(foo::bar-qux);
为什么
baz
的变形形式提到
foo
?为什么不是Z3bazIiEvi


这显然是C++17
std::default\u order
提案陷入僵局的原因。

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

两个不同的函数模板可能具有相同的函数返回类型和函数参数列表,即使重载解析本身无法区分它们

您可以在不同的文件中使用另一个函数

template <typename T>
void baz(int quux) { std::abort(); }
模板
voidbaz(int-qux){std::abort();}
虽然该签名不能和平共存于同一个文件中(由于过载模糊,无法命名),但它可以存在于另一个文件中,因此需要明显的损坏

(标准并不能保证所有模板都能达到这种共存水平。编译器使用函数模板声明的精确形式来执行声明匹配是一个质量问题,因此,将声明复制粘贴到定义中往往会提供精确匹配,而不会与另一个函数发生意外冲突解析为相同签名的离子模板。见§14.5.6.1/5-6。)


至于
default\u-order
的游行,问题是模板ID隐式地从模板中提取默认参数。因此,用户可能无意中在签名中包含一个依赖的typename,只需提及
std::set

,这样当需要时,它看起来就像源代码?I untaged[gcc]因为作为一个ABI问题,它也适用于CLAN等。我复制了Clang的问题,这是非常令人惊讶的…难以置信这是符合C++标准的。所以第一步是检查事实是否确实。它确实是,ItAuthabi不是GCC的。但是我标记了[GCC ]。无论如何,因为我觉得gcc专家可能有必要的知识来回答这个问题。此外,我相信许多损坏规则是由gcc发明的,并在以后编入安腾ABI,不是吗?@Barry Nonconconformance,如果你能观察到存在一个不同的符号,例如,如果一个专业的两个名称产生dif不同的地址。起初我以为Clang让我两次生成一个专门化,但事实并非如此。谢谢!你确定
template void baz(int)
实际上允许在单独的翻译单元中使用吗?我一直认为这是“格式错误,无需诊断”中的一种事情。特别是,MSVC显然以同样的方式破坏了两者。这真的不符合要求吗?@TavianBarnes NDR根据§14.5.6.1/6的规定是可能的,如果它们“功能等同但不等同”规则指定根据仅为表达式定义的过程来比较模板声明有点奇怪,因此当我们只有类型时,它会讨论值。我将编辑…“功能等效”表示“对于任何给定的模板参数集,表达式的计算结果都是相同的值”。即使将类似规则应用于类型,它也不会应用于
默认\u顺序
,这意味着专门化以返回不同的内容。您似乎将“for any”理解为“存在any”。我将其理解为“for every”,因此两个表达式“功能等效”仅当不存在两个表达式将产生不同值的参数集时。请注意,“功能等效”是两个函数模板的属性,而不是两个函数模板的专门化,因此您似乎在说
模板无效f(a);模板无效f(a);
是格式不正确的NDR,这对我来说毫无意义。@potatosatter No、
I+J
I*J
在我的阅读中在功能上是不等价的,因为存在一些参数集,它们的值不相同(例如,
I=1,J=1
)。您阅读的是“for any”∃, 我把它读作∀. 事实上,在您的阅读中,即使是[temp.over.link]/4中上面的两段示例也可能是格式不正确的NDR。如果这就是目的,我无法想象他们为什么不在那里调用它。