问题标签 [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 回答
5858 浏览

c++ - Should custom containers have free begin/end functions?

When creating a custom container class that plays by the usual rules (i.e. works with STL algorithms, works with well-behaved generic code, etc.), in C++03 it was sufficient to implement iterator support and member begin/end functions.

C++11 introduces two new concepts - range-based for loop and std::begin/end. Range-based for loop understands member begin/end functions, so any C++03 containers support range-based for out of the box. For algorithms the recommended way (according to 'Writing modern C++ code' by Herb Sutter) is to use std::begin instead of member function.

However, at this point I have to ask - is the recommended way to call a fully qualified begin() function (i.e. std::begin(c)) or to rely on ADL and call begin(c)?

ADL seems useless in this particular case - since std::begin(c) delegates to c.begin() if possible, usual ADL benefits do not seem to apply. And if everybody starts to rely on ADL, all custom containers have to implement extra begin()/end() free functions in their requisite namespaces. However, several sources seem to imply that unqualified calls to begin/end are the recommended way (i.e. https://svn.boost.org/trac/boost/ticket/6357).

So what is the C++11 way? Should container library authors write extra begin/end functions for their classes to support unqualified begin/end calls in absence of using namespace std; or using std::begin;?

0 投票
2 回答
313 浏览

c++ - VS2012 上的 decltype 内没有 ADL

我刚刚意识到尝试通过 decltype 获取函数的返回类型不涉及 VS2012 上的 ADL(参数相关查找)(使用 cl.exe V17.00.60610.1 测试)。

下面的例子

在 VS2012 上

但是(预期的):

在 gcc 4.7.3 上。

因此,ADL 在调用函数(输出中的第 1 行)时有效,但在 VS2012 上的 decltype 内使用时无效。

还是我错过了一些不同的观点?

0 投票
1 回答
254 浏览

c++ - 哪个函数用于初始化静态类成员?

我有一个关于选择哪个函数来初始化静态类成员的问题。

该变量Base::count是使用Base::countInit()而不是countInit()在 Base.cpp 中定义的进行初始化的。但是local_count是由本地初始化的countInit。所以,我想知道,在这种情况下是否有像Koenig 查找这样的规则?

0 投票
3 回答
524 浏览

c++ - 同名成员函数的 ADL

情况是某些成员函数bar::Bar::frobnicate想利用 ADL 从某个未知名称空间中找到一个函数,该函数在一个具有相同名称的函数中。但是,它只能找到自己的名称。

测试用例

请注意,实际上,Bar是一个Foo不可知的模板;这只是可重现的最小测试用例)

结果是:

标准

我知道这是正确的编译器行为:

3.4.1 非限定名称查找[basic.lookup.unqual]

(...) 一旦找到名称 (...) 的声明,名称查找就会结束

并且只有不合格的查找失败后,依赖于参数的查找才起作用:

3.4.2 依赖于参数的名称查找[basic.lookup.argdep]

当函数调用 (5.2.2) 中的后缀表达式是非限定 ID 时,可能会搜索在通常的非限定查找 (3.4.1) 期间未考虑的其他命名空间

解决方法

我目前的解决方法是引入一个不定义冲突名称本身的特殊特征类:

或者这个更轻的版本:

问题

有没有比引入此类特征类更好的选择?

在这里明确限定调用foo::frobnicate(foo)不是一个选项,因为(如前所述)Bar该类实际上是一个模板,Foo并且不应仅适用于foo命名空间中的类型。

0 投票
6 回答
3509 浏览

c++ - Bjarne 对这个 ADL 示例是否有错误,或者我有编译器错误?

我正在阅读The C++ Programming Language, 4th Edition (by Bjarne Stroustrup ) 关于。这是引用(26.3.6,过度激进的 ADL):

依赖于参数的查找(通常称为 ADL)对于避免冗长(14.2.4)非常有用。例如:

如果没有依赖于参数的查找,endl将找不到操纵器。实际上,编译器注意到 的第一个参数<<是在ostream中定义的std。因此,它查找endlinstd并找到它 (in <iostream>)。

这是编译器产生的结果(C++11 模式):

这是编译器或书中的错误。标准是怎么说的?

更新:

我需要澄清一下。我知道正确的答案是使用std::endl. 问题是关于书中的文字。正如Lachlan Easton已经说过的,这不仅仅是一个错字。整个段落(可能)是错误的。如果这本书是另一位(鲜为人知的)作者写的,我可以接受这种错误,但我一直(现在仍然)怀疑,因为它是由 Bjarne 写的。

0 投票
1 回答
334 浏览

c++ - 是否可以获取 ADL 函数的地址?

是否可以获取通过 ADL 找到的函数的地址?

例如:

0 投票
4 回答
655 浏览

c++ - 通过使用指令调用开始和结束?

调用的既定习惯用法swap是:

这样,swap可以为std命名空间之外的用户定义类型重载。

我们应该以同样的方式调用beginand吗?end

或者我们应该写:

0 投票
1 回答
1905 浏览

c++ - 为什么编译器找不到这个 operator<< 重载?

我正在尝试为operator<<将存储在boost::variant. 这是一个说明问题的小例子:

Clang 的第一个错误是

我意识到这#include <boost/variant.hpp>是在一个奇怪的地方。我很确定这个问题与模板中的两阶段名称查找有关,所以我移动了#include它以尝试从关于 lookup 的 clang 文档中实现修复 #1 。该文档中的修复 #2 不是一个好的选择,因为我相信将重载的 operator<< 添加到 std 命名空间会导致未定义的行为。

不应该在允许编译器找到定义operator<<之前定义 my s吗?#include该技术似乎适用于以下示例,改编自同一个 clang 页面。

0 投票
4 回答
2227 浏览

c++ - find() 使用重载的 operator==

我尝试使用重载运算符==() 在向量中查找元素。但是,如果type1在以下代码中使用,则输出为 1 和 0(未找到)。Usingtype2给出 1 和 1。环境是 Xubuntu 12.04 和 g++ 版本 4.6.3。

0 投票
1 回答
406 浏览

c++ - 我需要对 Stroustrup 关于 ADL 的新书中的这个例子进行一些澄清

我在 Stroustrup 书(第 4 版)第 396 页和第 397 页中给出的参数相关查找(ADL)示例下方重现:

上面的评论说的是正确的(我已经测试过了),但这似乎与作者在下一段中所说的不一致:

在标准中,依赖于参数的查找规则是根据关联的命名空间来表述的(iso §3.4.2)。基本上:

  • 如果参数是类成员,则关联的命名空间是类本身(包括其基类)和类的封闭命名空间。
  • 如果参数是命名空间的成员,则关联的命名空间是封闭的命名空间。
  • 如果参数是内置类型,则没有关联的命名空间。

在示例中x,具有 typeN::S的 不是 class 的成员D,也不是其 base的成员Base。但它是namespace N. 根据上面的第二个项目符号,该函数N::f(S)应该是被调用的函数,而不是Base::f().

上面的结果似乎也与标准中第 3.4.2p2 段中的第二个项目符号不一致,其中说:

如果 T 是类类型(包括联合),则其关联的类是:类本身;它所属的类别(如有的话);及其直接和间接基类。其关联名称空间是其关联类是其成员的名称空间。此外,如果 T 是类模板特化,则其关联的命名空间和类还包括: 与为模板类型参数(不包括模板模板参数)提供的模板实参类型相关联的命名空间和类;任何模板模板参数都是其成员的命名空间;以及用作模板模板参数的任何成员模板是其成员的类。