Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ISO C++ draft - 3.4.2/3 - Argument Dependant Name Lookup

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?

like image 977
user751747 Avatar asked Oct 11 '22 08:10

user751747


1 Answers

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
}
like image 196
TonyK Avatar answered Oct 12 '22 21:10

TonyK