当前位置: 首页 > 知识库问答 >
问题:

依赖名称的参数相关查找

国斌斌
2023-03-14

这是关于cppreference的描述。com说

模板中使用的依赖名称的查找将推迟到模板参数已知时,此时[…]ADL检查从模板定义上下文或模板实例化上下文可见的具有外部链接的函数声明。

与此相反,以下代码段可以使用三个编译器(MSVC、clang、gcc)很好地编译:

template <class T>
void CallFoo ()
{
    Foo (T ());
}


class Apple {};


int main ()
{
    CallFoo<Apple> ();
}


static void Foo (Apple)
{
}

Foo是CallFoo中的从属名称:它取决于模板参数T。但是,尽管违反了上述两条规则,编译器还是找到了函数Foo。

  • CallFoo的定义或实例化中都看不到Foo的声明,因为它位于两者之下。
  • Foo有内部链接。

这三个编译器不太可能都有bug。我可能误解了什么。你能详细说明一下吗?

共有1个答案

戈建白
2023-03-14

在C 03中,匿名命名空间的成员可以具有外部链接,尽管在其他翻译单元中无法命名。因此,人们认为可以从依赖的ADL中排除实际的静态函数。在C 11中,匿名命名空间施加了内部链接,因此限制变得不合理。然而,尽管实现采用了新行为并且在2011年立即提出了一个问题(如评论中指出的),但在2019年3月N4810之前,措辞仍保留在两个地方。

至于函数的位置,这是一个具有多个实例化点的函数的工件,包括实例化它们的任何翻译单元的末端(对于C 20中的模块有轻微的调整);如果实例化函数模板会为不同的选择产生不同的结果,则程序的格式不正确,无需进行诊断(如注释中所述)。

 类似资料:
  • 当我尝试编译这段代码时 对于g 4.8.2,我得到以下错误消息 (与3.4版本的叮当声几乎相同)。 首先,我认为代码是正确的,应该进行编译,因为foobar是模板声明中的一个依赖名称,应该仅在模板实例化的第二阶段进行查找。在最后一行中完成此操作时,已声明“foobar(int)”。顺便说一句,当我取消注释最上面的行时,代码会编译,但这两个声明都在实例化之前,所以这应该无关紧要。 其次,我觉得错误信

  • 我不太清楚kotlin是如何管理属性名和主构造函数参数名的。如果我写了相同的属性名和参数名,那么kotlin编译器会给出一个错误。 它给出了这个错误。 但是,当我更改属性的名称或更改主构造函数的参数名称时,代码将工作并编译。 这将工作或编译罚款。 这背后的原因是什么?为什么主构造函数的参数名和属性名不能相同?

  • 我有一些代码无法编译,我将其简化为以下最低版本: 在魔杖盒上看到 Clang(9.0.0)拒绝了这一点: Clang说是一个依赖的模板名称是对的吗?VS 2017没有问题。GCC(9.2.0)也拒绝该代码,但错误消息更加模糊: 按照叮当的建议改变冒犯的路线 修复Clang和GCC的编译。VS2017也接受此版本。 解决方案似乎很简单,但如果我重新排序函数调用: 或从 中删除参数: 错误消失了。 这

  • 问题内容: 我正在尝试将一个旧项目迁移到Retrofit库,并且该项目具有相当棘手的API。所以我有一个这样的查询模板: 我必须在以下模板的此处添加一些参数: 例如: 这就是API的工作方式,我无法更改。我知道我们可以将列表作为参数传递,如下所示: 但是,如何动态设置参数名称呢? 问题答案: 感谢@ILLIA DEREVIANKO(https://github.com/square/retrofi

  • 我们都知道依赖树对于解决可传递依赖冲突至关重要。对于,情况也是如此,但我找不到一种方法,可以像那样打印依赖关系树。 有没有插件或其他东西可以帮助你? Maven版本:3.2.3 编辑 对于认为这个问题与另一个问题重复的人,请考虑: > 另一个问题是关于依赖关系管理的插件管理。 另一个问题与生成依赖关系树无关。

  • 本文向大家介绍什么是C ++中的“依赖于参数的查找”(“ Koenig查找”)?,包括了什么是C ++中的“依赖于参数的查找”(“ Koenig查找”)?的使用技巧和注意事项,需要的朋友参考一下 依赖参数的查找(ADL)是一种用于在函数调用表达式中查找不合格函数名称的协议。 这些函数调用表达式包括对重载运算符的隐式函数调用。 除了通常的非限定名称查找所考虑的范围和命名空间之外,还在其参数的命名空间