问题标签 [argument-dependent-lookup]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
139 浏览

c++ - ADL 与范围解析——更喜欢哪个?

我如何判断我是否应该使用

代替

调用我的函数时foo(不在我的直接范围内)?是否有一个通用的“规则”来确定是否应该使用 ADL?我应该“默认”使用哪一个?

0 投票
2 回答
2097 浏览

c++ - 为什么参数依赖查找不适用于函数模板 dynamic_pointer_cast

考虑以下 C++ 程序:

使用 MSVC 2010 编译时,出现以下错误:

如果auto替换为,错误仍然存​​在std::shared_ptr<A>。当我用 完全限定调用时std::dynamic_pointer_cast,程序成功编译。

此外,gcc 4.5.1也不喜欢它:

我认为Koenig lookupstd::dynamic_pointer_cast会选择它,因为类型存在于命名空间中。我在这里想念什么?xstd

0 投票
2 回答
316 浏览

c++ - 有 lambda 参数时 ADL 失败?

很久以前,我注意到在 Visual C++ 10 中,当至少一个参数是 lambda 时,ADL 会失败。

以上无法在 VC++10 和 11 (beta) 上编译(通过 ADL 找到开始和结束)。当我将 lambda 函数转换为常规的自由函数时,事情会按预期工作。

我曾经在 Herb Sutters 博客上问过一次,还阅读了 msdn connect 上的一些帖子,通常的答案是:这是一个错误,我们还没有实现 lambdas 的最新标准,这在当时是可以理解的。事情还没有成熟。在 MS connect 上,也有令人不安的评论,即下一个版本(即 vc 11)将无法解决此问题。

我的问题是,这段代码是否可以在 C++11 标准下工作?我不能完全弄清楚。当我使用 lambdas 时,我真的必须在我的 for_each 和其他算法前面加上 std:: 吗?我怀疑这种行为在 vc++11 发布后不会改变。

0 投票
2 回答
113 浏览

c++ - 如何从重载集中删除当前函数?

我的命名空间中有一个函数ns::foo,它的工作是调度foo使用参数相关查找的调用:

我希望客户能够调用foo而无需手动实例化它,即:

不是

当然,问题ns::foo是如果没有foo比更好的匹配,那就是递归的ns::foo

我不想给ns::foo一个不同的名字,那么有什么办法可以将它从内部的重载集中删除?

0 投票
2 回答
266 浏览

c++ - ADL在特定情况下不起作用

我制作了如下 is_iterable 模板——它检查自由函数开始/结束是否可用(在 ADL 的上下文中)并返回正确的迭代器对象。(这是 ranged-for 循环中可迭代对象的要求)

上面的代码在 vs2010 中完全按照预期工作,但在 gcc 中却没有。此外,当我如下放置一些名为'begin'的随机免费函数时,即使在vs2010中它也会被破坏。

我怎样才能使代码工作?此外,任何改进“is_iterable”概念检查器的建议都将不胜感激。

补充:“写”功能只是一个概念演示示例 - 请不要将您的宝贵时间投入到它上面。(我知道这不是最好的代码:()需要注意的部分是 ADL 行为和“is_iterable”模板:)

0 投票
2 回答
777 浏览

c++ - 依赖于参数的查找是否也只搜索名称空间或类?

我一直在阅读 Josuttis 模板书,并且一直在尝试将头放在 ADL 上。他说“ADL 通过在命名空间和类中查找名称来“与”调用参数的类型“相关联”。我只是想看看它是如何在班级中查找名称的。我在下面放了一个测试示例。我看到它如何在命名空间中查找名称。

但是,如果我将 bryan_ns 更改为这样的命名空间:

0 投票
4 回答
3296 浏览

c++ - 为 C++ 模板类提供 swap() 会破坏 std::swap()?

我试图在我的自定义 Matrix 类中实现复制和交换习语,但我在以链接到问题中建议的方式实现 swap() 时遇到了一些麻烦:

(我使用的编译器是MS VS2010 IDE的编译器,方言是很好的老式C++03。)

现在我无法在代码中为驻留在此命名空间中的函数访问常规 std::swap() :

不幸的是,由于某种原因,my_space::swap()对于 Matrix 似乎将所有其他调用别名为std::swap(),我不知道为什么因为参数不适合并且 ADL 应该支持std::swap

(对于我尝试使用的每一行,错误都会重复 10 次std::swap

my_space::swap()总是否决std::swap()in my_space,即使论点不合适?它不是std::swap()不可见的,它在my_space::swap()创建之前工作正常。

0 投票
1 回答
720 浏览

c++ - 通过模板类的基础进行依赖于参数的查找

我有一个从命名空间中NB::B<T>的非模板类派生的模板类NA::A。是在其模板参数的实例上act<T>调用函数的模板函数。add_ref具体来说,act<NB::B<int>>想使用 ADL查找add_ref定义在 's base 的命名空间中。NB::B完整的例子如下:

gcc这在(4.7.0)中编译得很好。并且在Comeau网上。但是clang(3.1)失败了:

同时,标准中写道:

3.4.2/2 …</p>

— 如果 T 是模板 ID,则其关联的命名空间和类是定义模板的命名空间;对于成员模板,成员模板的类;与为模板类型参数(不包括模板模板参数)提供的模板参数的类型相关联的命名空间和类;定义任何模板模板参数的命名空间;以及定义用作模板模板参数的任何成员模板的类。

令人惊讶的是,模板的基础并未列为关联命名空间的路径。因此clang的行为似乎是正确的。并且正在接受不正确的程序Comeaugcc

同时,参数命名空间中的 '3.4.2/3声明using无效:

在考虑关联命名空间时,查找与将关联命名空间用作限定符 (3.4.3.2) 时执行的查找相同,除了:

— 相关命名空间中的任何 using 指令都将被忽略。

但是当我取消注释时,该using NA::add_refclang很高兴编译测试。

把我的例子放到实际的角度来看,你可以认为那act是一个方法boost::intrusive_ptradd_ref(A*)曾经intrusive_ptr_add_ref(CBase*)B曾经是一些模板,从 base 派生CBase

关于这个我有几个问题:

  1. 拒绝我clang的测试程序gcc并且Comeau不遵循标准是正确的吗?

  2. 标准指定这种不切实际的行为(不允许模板类基作为关联的命名空间)是否有原因?

  3. clang基于以下原因接受我的测试程序与using NA::add_ref指令是错误的3.4.2/3吗?

  4. 我应该报告错误吗?:)

PS 我已阅读clang Language Compatibility FAQ并没有在那里找到答案。

0 投票
1 回答
121 浏览

c++ - 依赖于参数的名称查找:添加额外的名称空间以查看

我想利用 ADL 规则来检查额外命名空间中的函数:

假设我们有一个class X.

通话中

我希望编译器查看namespace funky,直到现在与class X. 但我不想通过funky::f在调用时放置来混淆编码f

实现此目的的一种方法是定义class X为模板类,其参数来自namespace funky.

对于一个调用f(x),现在,编译器确实会寻找funky::f.

是否有更清洁/更简单的方法来实现相同的行为?(特别是,someClassFromFunky在声明中引用一些任意类class X是很尴尬的。)

0 投票
1 回答
1064 浏览

c++ - 模板实例化上的 C++11 样式 SFINAE 和函数可见性

我不确定这是否与 sfinae 有任何关系,或者只是与任何模板化函数相关的东西。我正在尝试使用 sfinae 基于相应自由函数的存在来启用/禁用成员函数,而该自由函数又根据另一种类型的成员函数的存在来启用/禁用,所有这些都使用此处描述的方法:

但是 gcc 4.7.1 在箭头标记的行上给了我这个:

错误:没有用于调用“S::f(S&, const pass&)”的匹配函数
注意:候选是:
注意:模板 decltype ((f((* this), t), void())) S::f (const T&)
注意:模板参数推导/替换失败:
注意:候选人需要 1 个参数,提供 2 个

这显然意味着f上面的全局不被考虑用于重载解决方案。

为什么会这样,我该怎么做才能做到这一点?

另外为什么上面两行没有错误,f在 decltype 中以类似的方式使用?

更新

正如@nm 所说,成员函数完全隐藏自由函数,即使它们的签名不同,所以这里有一个不会破坏 ADL 的解决方法f(与 @nm 建议的全名限定不同)。f_dispatcher在没人会看到的地方()创建自由函数(detail),并在里面完全限定它的名字S::f。在该函数中调用 freef并让 ADL 从那里开始处理它,如下所示: