Черновик ISO C ++ - 3.4.2 / 3 - поиск имени в зависимости от аргумента - PullRequest
5 голосов
/ 03 августа 2011

Точка из черновика ISO C ++ (n3290):

3.4.2 / 3 Аргумент Зависимый поиск имени:

Пусть X будет поисковым набором, произведенным неквалифицированным поиском (3.4.1) и пусть Y будет набором поиска, созданным зависимым от аргумента поиском (определяется следующим образом). Если X содержит

  • объявление члена класса (# 1) или
  • функция блока объявление, которое не является объявлением об использовании (# 2) или
  • декларация это не функция или шаблон функции (# 3)

тогда Y пусто. В противном случае Y - это набор объявлений, найденных в пространства имен, связанные с типами аргументов, как описано ниже. Набор объявлений, найденных при поиске имени, является объединением X и Y.

Есть ли пример кода, который демонстрирует ADL с участием # 1, # 2 и # 3?

Ответы [ 3 ]

3 голосов
/ 03 августа 2011

Я думаю, что этот код охватывает все случаи (также доступен в http://ideone.com/CbyJv).. Если вы не выбираете C ++ 0x в ideone, тогда случай # 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
}
1 голос
/ 03 августа 2011

Номер 1 довольно прост - если вы ищете имя N внутри класса, и у класса есть член N, вот и все! Тебе не нужно искать где-то еще.

Номер 2, я думаю, похож, но внутри блока

{
    void f(double);

    f(42);
}

код будет пытаться вызвать объявленную там функцию f, если это возможно, и отказаться от нее в противном случае.

Номер 3 снова похож. Если вы ищете имя N и находите что-то с этим именем, которое не является функцией, вам не нужно искать перегрузки.

0 голосов
/ 03 августа 2011

Для чего это стоит, это также называют Поиск Кенига.У меня нет примеров для всех 3, но Бо Перссон уже предоставил некоторые.

...