我认为这段代码涵盖了所有情况(也可在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
}