ISO C++草稿 - 3.4.2/3 - 参数相关名称查找

发布于 2024-11-27 18:44:05 字数 510 浏览 1 评论 0原文

ISO C++ 草案 (n3290) 中的一点:

3.4.2/3 参数相关名称查找:

X为非限定查找(3.4.1)产生的查找集,并且 令 Y 为参数相关查找生成的查找集 (定义如下)。如果X包含

  • 类成员的声明 (#1) 或
  • 块作用域函数 声明不是 using 声明 (#2) 或
  • 声明 这既不是函数也不是函数模板 (#3)

那么Y为空。否则 Y 是在中找到的声明集 与参数类型关联的命名空间,如下所述。 通过名称查找找到的声明集是并集 XY

是否有一个示例代码片段演示涉及 #1、#2 和 #3 的 ADL?

A point from the ISO C++ draft (n3290):

3.4.2/3 Argument Dependant Name Lookup:

Let X be the lookup set produced by unqualified lookup (3.4.1) and
let Y be the lookup set produced by argument dependent lookup
(defined as follows). If X contains

  • a declaration of a class member (#1) or
  • a block-scope function
    declaration that is not a using-declaration (#2) or
  • a declaration
    that is neither a function or a function template (#3)

then Y is empty. Otherwise Y is the set of declarations found in
the namespaces associated with the argument types as described below.
The set of declarations found by the lookup of the name is the union
of X and Y.

Is there an example code snippet that demonstrates ADL involving #1, #2 and #3?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

金橙橙 2024-12-04 18:44:05

我认为这段代码涵盖了所有情况(也可在 http://ideone.com/CbyJv 获取)。如果您不在 ideone 中选择 C++0x,则允许情况#2(但 gcc 4.5.2 捕获它)。

#include <iostream>

// ::f
void f (int i) { std::cout << "::f\n" ; }

// Simple case
void OK1() {
  f (99) ; // Calls ::f
}

// Argument-dependend lookup
namespace MyNamespace {
struct S { int i ; } ;
void f (S& s) { std::cout << "MyNamespace::f\n" ; }
}

void OK2() {
  MyNamespace::S s ;
  f (99) ;   // Calls ::f
  f (s) ;    // Calls MyNamespace::f because the type of s is declared in MyNamespace
}

// Declaration of a class member (#1)
struct C {
  static void ERROR1() {
    MyNamespace::S s ;
    f (s) ;        // Error: MyNamespace::f not matched, because Y is empty (#1)
  }
  static void f() { // Declaration of a class member (#1)
    std::cout << "C::f\n" ;
  }
} ;

// Block-scope function declaration (#2)
void ERROR2() {
  void f() ; // Block-scope function declaration (#2)
  MyNamespace::S s ;
  f (s) ;    // Error: MyNamespace::f not matched, because Y is empty (#2)
}

// Declaration that is neither a function or a function template (#3)
void ERROR3() {
  MyNamespace::S s ;
  f (s) ;            // OK: MyNamespace::f called
  typedef int f[3] ; // Declaration that is neither a function or a function template (#3)
  f (s) ;            // Error: MyNamespace::f not matched, because Y is empty (#3). This is an initialiser
}

I think this code covers all the cases (also available at http://ideone.com/CbyJv). If you don't select C++0x in ideone, then case #2 is allowed (but gcc 4.5.2 catches it).

#include <iostream>

// ::f
void f (int i) { std::cout << "::f\n" ; }

// Simple case
void OK1() {
  f (99) ; // Calls ::f
}

// Argument-dependend lookup
namespace MyNamespace {
struct S { int i ; } ;
void f (S& s) { std::cout << "MyNamespace::f\n" ; }
}

void OK2() {
  MyNamespace::S s ;
  f (99) ;   // Calls ::f
  f (s) ;    // Calls MyNamespace::f because the type of s is declared in MyNamespace
}

// Declaration of a class member (#1)
struct C {
  static void ERROR1() {
    MyNamespace::S s ;
    f (s) ;        // Error: MyNamespace::f not matched, because Y is empty (#1)
  }
  static void f() { // Declaration of a class member (#1)
    std::cout << "C::f\n" ;
  }
} ;

// Block-scope function declaration (#2)
void ERROR2() {
  void f() ; // Block-scope function declaration (#2)
  MyNamespace::S s ;
  f (s) ;    // Error: MyNamespace::f not matched, because Y is empty (#2)
}

// Declaration that is neither a function or a function template (#3)
void ERROR3() {
  MyNamespace::S s ;
  f (s) ;            // OK: MyNamespace::f called
  typedef int f[3] ; // Declaration that is neither a function or a function template (#3)
  f (s) ;            // Error: MyNamespace::f not matched, because Y is empty (#3). This is an initialiser
}
陌若浮生 2024-12-04 18:44:05

第 1 点非常简单 - 如果您在类中查找名称 N,并且该类有一个成员 N,就是这样!您不必去其他地方寻找。

我认为第二个是类似的,但是在一个块内,

{
    void f(double);

    f(42);
}

如果可能的话,代码将尝试调用在那里声明的函数 f,否则放弃。

3号又是类似的。如果您查找名称 N 并找到具有该名称但不是函数的内容,则不必去寻找重载。

Number 1 is pretty simple - if you look for a name N inside a class, and the class has a member N, that's it! You don't have to go looking anywhere else.

Number 2 I believe is similar, but inside a block

{
    void f(double);

    f(42);
}

the code will try to call the function f declared there, if possible, and give up otherwise.

Number 3 is again similar. If you look for the name N and find something with that name that is not a function, you don't have to go looking for overloads.

飘逸的'云 2024-12-04 18:44:05

就其价值而言,这也称为 Koenig 查找。我手头上没有这三个例子,但 Bo Persson 已经提供了一些。

For what it's worth, this is also called a Koenig Lookup. I don't have examples for all 3 to hand, but Bo Persson has already provided some.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文