Namespaces
Variants

Unqualified name lookup

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

비한정(unqualified) 이름, 즉 범위 지정 연산자 :: 의 오른쪽에 나타나지 않는 이름에 대해, 이름 검색(name lookup)은 아래에 설명된 대로 범위(scope) 를 조사하여 어떠한 종류의 선언(declaration)이라도 최소한 하나를 찾을 때까지 계속되며, 이때 검색이 중지되고 더 이상의 범위는 조사되지 않습니다. (참고: 일부 컨텍스트(context)에서의 검색은 일부 선언을 건너뛰는데, 예를 들어 :: 의 왼쪽에 사용된 이름의 검색은 함수, 변수, 열거자(enumerator) 선언을 무시하며, 기본 클래스 지정자(base class specifier)로 사용된 이름의 검색은 모든 비타입(non-type) 선언을 무시합니다).

비정규 이름 검색(unqualified name lookup)의 목적상, using 지시문 으로 지정된 네임스페이스의 모든 선언들은, using 지시문과 지정된 네임스페이스를 직접적 또는 간접적으로 포함하는 가장 가까운 둘러싸는 네임스페이스에 선언된 것처럼 나타납니다.

함수 호출 연산자(그리고 동등하게 표현식 내 연산자)의 왼쪽에 사용된 이름에 대한 비한정 이름 검색은 인수 의존적 검색 에서 설명됩니다.

목차

파일 범위

전역(최상위 네임스페이스) 범위에서 사용되는 이름의 경우, 어떤 함수, 클래스, 또는 사용자 선언 네임스페이스 외부에서 해당 이름 사용 이전의 전역 범위가 검사됩니다:

int n = 1;     // n의 선언
int x = n + 1; // OK: lookup이 ::n을 찾음
int z = y - 1; // Error: lookup 실패
int y = 2;     // y의 선언

네임스페이스 범위

사용자가 선언한 네임스페이스 내에서 함수나 클래스 외부에서 사용된 이름의 경우, 해당 이름 사용 전에 이 네임스페이스를 검색한 다음, 이 네임스페이스의 선언 전에 이 네임스페이스를 둘러싼 네임스페이스를 검색하는 등의 과정을 통해 전역 네임스페이스에 도달할 때까지 계속됩니다.

int n = 1; // 선언
namespace N
{
    int m = 2;
    namespace Y
    {
        int x = n; // OK, 조회가 ::n을 찾음
        int y = m; // OK, 조회가 ::N::m을 찾음
        int z = k; // 오류: 조회 실패
    }
    int k = 3;
}

네임스페이스 외부에서의 정의

네임스페이스-멤버 변수의 정의에서 네임스페이스 외부에서 사용된 이름의 경우, 네임스페이스 내부에서 사용된 이름과 동일한 방식으로 조회가 진행됩니다:

namespace X
{
    extern int x; // 선언, 정의 아님
    int n = 1;    // 첫 번째로 발견됨
}
int n = 2;        // 두 번째로 발견됨
int X::x = n;     // X::n을 찾아서 X::x를 1로 설정

비멤버 함수 정의

함수의 정의 내에서 사용된 이름에 대하여, 함수 본문 내에서 또는 기본 인자의 일부로 사용될 때, 해당 함수가 사용자 정의 또는 전역 네임스페이스의 멤버인 경우, 이름이 사용된 블록은 이름 사용 전에 검색되며, 그 다음 해당 블록의 시작 전에 둘러싸는 블록이 검색되는 방식으로 함수 본문인 블록에 도달할 때까지 계속됩니다. 그런 다음 함수가 선언된 네임스페이스는 이름을 사용하는 함수의 정의(반드시 선언이 아닌)까지 검색된 후, 둘러싸는 네임스페이스 등이 검색됩니다.

namespace A
{
    namespace N
    {
        void f();
        int i = 3; // 3번째로 발견됨 (2번째가 없는 경우)
    }
    int i = 4;     // 4번째로 발견됨 (3번째가 없는 경우)
{
int i = 5;         // 5번째로 발견됨 (4번째가 없는 경우)
void A::N::f()
{
    int i = 2;     // 2번째로 발견됨 (1번째가 없는 경우)
    while (true)
    {
       int i = 1;  // 1번째로 발견됨: 조회 완료
       std::cout << i;
    }
}
// int i;          // 발견되지 않음
namespace A
{
    namespace N
    {
        // int i;  // 발견되지 않음
    }
}

클래스 정의

클래스 정의 내 어디에서든 사용되는 이름(멤버 함수 본문 내부, 멤버 함수의 기본 인자, 멤버 함수의 예외 명세, 또는 기본 멤버 초기화자를 제외하며, 해당 멤버가 바깥쪽 클래스의 본문 내에 정의된 중첩 클래스에 속할 수 있는 경우)에 대해 다음 스코프들이 검색됩니다:

a) 이름이 사용된 지점까지 해당 이름이 사용된 클래스의 본문,
b) 해당 기본 클래스(들)의 전체 본문, 선언이 발견되지 않을 경우 해당 기본 클래스들로 재귀적으로 진행,
c) 이 클래스가 중첩된 클래스인 경우, 이 클래스의 정의까지의 외부 클래스 본문과 외부 클래스의 기반 클래스(들)의 전체 본문,
d) 이 클래스가 local 클래스이거나 local 클래스 내에 중첩된 경우, 클래스가 정의된 블록 범위부터 정의 지점까지,
e) 이 클래스가 네임스페이스의 멤버이거나, 네임스페이스의 멤버인 클래스에 중첩되었거나, 네임스페이스의 멤버인 함수 내의 로컬 클래스인 경우, 클래스, 외부 클래스 또는 함수의 정의까지 네임스페이스의 스코프가 검색됩니다; 룩업은 해당 네임스페이스를 둘러싼 네임스페이스들로 계속되어 전역 스코프까지 진행됩니다.

friend 선언의 경우, 이전에 선언된 엔티티를 참조하는지 확인하기 위한 탐색은 가장 안쪽의 네임스페이스에서 멈춘다는 점을 제외하고는 위와 동일하게 진행됩니다.

namespace M
{
    // const int i = 1; // 절대 찾지 못함
    class B
    {
        // static const int i = 3;     // 3번째로 발견됨 (하지만 접근 검사를 통과하지 못함)
    };
}
// const int i = 5;                    // 5번째로 발견됨
namespace N
{
    // const int i = 4;                // 4번째로 발견됨
    class Y : public M::B
    {
        // static const int i = 2;     // 2번째로 발견됨
        class X
        {
            // static const int i = 1; // 1번째로 발견됨
            int a[i]; // i의 사용
            // static const int i = 1; // 절대 찾지 못함
        };
        // static const int i = 2;     // 절대 찾지 못함
    };
    // const int i = 4;                // 절대 찾지 못함
}
// const int i = 5;                    // 절대 찾지 못함

삽입된 클래스 이름

클래스나 클래스 템플릿의 정의 내에서, 또는 이들로부터 파생된 클래스에서 사용되는 클래스나 클래스 템플릿의 이름에 대해, 한정되지 않은 이름 조회(unqualified name lookup)는 해당 이름이 멤버 선언(public 멤버 접근 권한으로)에 의해 도입된 것처럼 정의 중인 클래스를 찾습니다. 자세한 내용은 injected-class-name 을 참조하십시오.

멤버 함수 정의

멤버 함수 본문 내부에서 사용된 이름, 멤버 함수의 기본 인자, 멤버 함수의 예외 명세, 또는 기본 멤버 초기화자에 대해 검색되는 스코프는 클래스 정의 에서와 동일하지만, 클래스의 전체 스코프가 고려되며 이름을 사용하는 선언 이전 부분만 고려되지 않는다는 점이 다릅니다. 중첩 클래스의 경우 둘러싼 클래스의 전체 본문이 검색됩니다.

class B
{
    // int i;         // 3번째로 발견됨
};
namespace M
{
    // int i;         // 5번째로 발견됨
    namespace N
    {
        // int i;     // 4번째로 발견됨
        class X : public B
        {
            // int i; // 2번째로 발견됨
            void f();
            // int i; // 2번째로 발견됨 (동일 순위)
        };
        // int i;     // 4번째로 발견됨
    }
}
// int i;             // 6번째로 발견됨
void M::N::X::f()
{
    // int i;         // 1번째로 발견됨
    i = 16;
    // int i;         // 발견되지 않음
}
namespace M
{
    namespace N
    {
        // int i;     // 발견되지 않음
    }
}
어느 쪽이든, 클래스가 파생된 베이스들을 검사할 때, 때로는 가상 상속에서의 우세성 이라고 불리는 다음 규칙들이 적용됩니다:
서브 객체 B 에서 발견된 멤버 이름은 A B 의 베이스 클래스 서브 객체인 경우, 모든 서브 객체 A 에 있는 동일한 멤버 이름을 가립니다. (이는 B 의 베이스가 아닌 상속 격자 구조에 있는 A 의 추가적인 비가상 복사본에서는 이름을 가리지 않습니다: 이 규칙은 가상 상속에만 영향을 미칩니다.) using 선언에 의해 도입된 이름들은 선언을 포함하는 클래스의 이름으로 처리됩니다. 각 베이스를 검사한 후, 결과 집합은 동일한 타입의 서브 객체에서 정적 멤버 선언을 포함하거나 동일한 서브 객체에서 비정적 멤버 선언을 포함해야 합니다. (C++11 이전)
조회 집합 이 구성되며, 이는 선언들과 이러한 선언들이 발견된 서브 객체들로 구성됩니다. using 선언은 그들이 나타내는 멤버들로 대체되고, 타입 선언(주입된 클래스 이름 포함)은 그들이 나타내는 타입들로 대체됩니다. 이름이 사용된 스코프의 클래스가 C 인 경우, C 가 먼저 검사됩니다. C 의 선언 목록이 비어 있으면, 각 직접 베이스 Bi 에 대해 조회 집합이 구축됩니다 ( Bi 가 자체 베이스를 가지고 있는 경우 이러한 규칙들을 재귀적으로 적용). 일단 구축되면, 직접 베이스들에 대한 조회 집합들은 다음과 같이 C 의 조회 집합으로 병합됩니다:
  • Bi 의 선언 집합이 비어 있으면 폐기됩니다,
  • 지금까지 구축된 C 의 조회 집합이 비어 있으면 Bi 의 조회 집합으로 대체됩니다,
  • Bi 의 조회 집합에 있는 모든 서브 객체가 이미 C 의 조회 집합에 추가된 서브 객체들 중 적어도 하나의 베이스인 경우, Bi 의 조회 집합은 폐기됩니다,
  • 이미 C 의 조회 집합에 추가된 모든 서브 객체가 Bi 의 조회 집합에 있는 적어도 하나의 서브 객체의 베이스인 경우, C 의 조회 집합은 폐기되고 Bi 의 조회 집합으로 대체됩니다,
  • 그렇지 않고, Bi C 의 선언 집합들이 다른 경우, 결과는 모호한 병합입니다: C 의 새로운 조회 집합은 유효하지 않은 선언과 이전에 C 로 병합된 서브 객체들과 Bi 에서 도입된 서브 객체들의 합집합을 가집니다. 이 유효하지 않은 조회 집합은 나중에 폐기되면 오류가 아닐 수 있습니다,
  • 그렇지 않으면, C 의 새로운 조회 집합은 공유된 선언 집합들과 이전에 C 로 병합된 서브 객체들과 Bi 에서 도입된 서브 객체들의 합집합을 가집니다.
(C++11 이후)
struct X { void f(); };
struct B1: virtual X { void f(); };
struct B2: virtual X {};
struct D : B1, B2
{
    void foo()
    {
        X::f(); // OK, X::f 호출 (정규화된 조회)
        f(); // OK, B1::f 호출 (비정규화 조회)
    }
};
// C++98 규칙: B1::f가 X::f를 숨기므로, X::f가 D에서 B2를 통해 접근 가능하더라도
// D에서의 이름 조회로는 찾을 수 없음
// C++11 규칙: D에서 f에 대한 조회 집합은 아무것도 찾지 못하고, 기본 클래스로 진행
//  B1에서 f에 대한 조회 집합은 B1::f를 찾고 완료됨
// 병합은 빈 집합을 대체하며, 이제 C에서 f에 대한 조회 집합은 B1에 있는 B1::f를 가짐
//  B2에서 f에 대한 조회 집합은 아무것도 찾지 못하고, 기본 클래스로 진행
//    X에서 f 조회는 X::f를 찾음
//  병합은 빈 집합을 대체하며, 이제 B2에서 f에 대한 조회 집합은 X에 있는 X::f를 가짐
// C로의 병합에서 B2의 조회 집합에 있는 모든 하위 객체(X)가 이미 병합된 모든 하위 객체(B1)의
// 기본 클래스임을 발견하므로 B2 집합은 버려짐
// C는 B1에서 찾은 B1::f만 남게 됨
// (만약 struct D : B2, B1를 사용했다면, 마지막 병합은 C의 지금까지 병합된
//  X::f in X를 *대체*할 것임. 왜냐하면 이미 C에 추가된 모든 하위 객체(즉 X)가
//  새 집합(B1)의 적어도 하나의 하위 객체의 기본 클래스가 되기 때문이며,
//  최종 결과는 동일함: C의 조회 집합은 B1에서 찾은 B1::f만 보유)
B 의 정적 멤버, B 의 중첩 타입, 그리고 B 내에서 선언된 열거자를 찾는 비한정 이름 검사는 검사 중인 클래스의 상속 트리에 B 타입의 다중 비가상 기반 하위 객체가 존재하더라도 명확합니다:
struct V { int v; };
struct B
{
    int a;
    static int s;
    enum { e };
};
struct B1 : B, virtual V {};
struct B2 : B, virtual V {};
struct D : B1, B2 {};
void f(D& pd)
{
    ++pd.v;       // OK: 가상 기본 클래스 서브오브젝트가 하나뿐이므로 v는 하나만 존재
    ++pd.s;       // OK: B1과 B2 모두에서 발견되더라도 static B::s는 하나만 존재
    int i = pd.e; // OK: B1과 B2 모두에서 발견되더라도 열거자 B::e는 하나만 존재
    ++pd.a;       // 오류, 모호함: B1의 B::a와 B2의 B::a
}

프렌드 함수 정의

클래스 내부에서 우정을 부여하는 클래스의 본문 안에 정의된 friend 함수 정의에서 사용된 이름에 대해서는, 한정되지 않은 이름 조회(unqualified name lookup)가 멤버 함수와 동일한 방식으로 진행됩니다. 클래스 본문 외부에 정의된 friend 함수에서 사용된 이름에 대해서는, 한정되지 않은 이름 조회가 네임스페이스 내의 함수와 동일한 방식으로 진행됩니다.

int i = 3;                     // f1에서 3번째로 발견, f2에서 2번째로 발견
struct X
{
    static const int i = 2;    // f1에서 2번째로 발견, f2에서는 발견되지 않음
    friend void f1(int x)
    {
        // int i;              // 1번째로 발견
        i = x;                 // X::i를 찾아 수정함
    }
    friend int f2();
    // static const int i = 2; // 클래스 범위 내 어디서나 f1에서 2번째로 발견
};
void f2(int x)
{
    // int i;                  // 1번째로 발견
    i = x;                     // ::i를 찾아 수정함
}

프렌드 함수 선언

다른 클래스의 멤버 함수를 프렌드로 선언하는 friend 함수 선언의 선언자에서 사용된 이름에 대해, 해당 이름이 declarator 식별자의 템플릿 인자 일부가 아닌 경우, 한정되지 않은 조회는 먼저 멤버 함수의 클래스 전체 범위를 검사합니다. 해당 범위에서 찾을 수 없는 경우(또는 이름이 선언자 식별자의 템플릿 인자 일부인 경우), 조회는 프렌드 권한을 부여하는 클래스의 멤버 함수에 대한 조회처럼 계속 진행됩니다.

template<class T>
struct S;
// 멤버 함수들이 friend로 선언될 클래스
struct A
{ 
    typedef int AT;
    void f1(AT);
    void f2(float);
    template<class T>
    void f3();
    void f4(S<AT>);
};
// f1, f2, f3에 대한 friend 권한을 부여하는 클래스
struct B
{
    typedef char AT;
    typedef float BT;
    friend void A::f1(AT);    // AT 조회 시 A::AT를 찾음 (A에서 AT 발견)
    friend void A::f2(BT);    // BT 조회 시 B::BT를 찾음 (A에서 BT 발견되지 않음)
    friend void A::f3<AT>();  // AT 조회 시 B::AT를 찾음 (선언자 식별자 A::f3<AT>에 AT가 있으므로
                              //     A에서 조회하지 않음)
};
// f4에 대한 friend 권한을 부여하는 클래스 템플릿
template<class AT>
struct C
{
    friend void A::f4(S<AT>); // AT 조회 시 A::AT를 찾음
                              // (AT가 선언자 식별자 A::f4에 없음)
};

기본 인수

함수 선언에서 기본 인자 에 사용된 이름, 또는 생성자의 멤버 초기화 표현식 부분에 사용된 이름에 대해서는, 함수 매개변수 이름이 먼저 찾아지며, 이후에 둘러싸는 블록, 클래스, 또는 네임스페이스 범위가 검사됩니다:

class X
{
    int a, b, i, j;
public:
    const int& r;
    X(int i): r(a),      // X::r을 X::a를 참조하도록 초기화합니다
              b(i),      // X::b를 매개변수 i의 값으로 초기화합니다
              i(i),      // X::i를 매개변수 i의 값으로 초기화합니다
              j(this->i) // X::j를 X::i의 값으로 초기화합니다
    {}
};
int a;
int f(int a, int b = a); // 오류: a에 대한 조회가 매개변수 a를 찾으며, ::a를 찾지 못함
                         // 그리고 매개변수는 기본 인수로 허용되지 않음

정적 데이터 멤버 정의

static data member 의 정의에서 사용된 이름에 대해, 이름 탐색(name lookup)은 멤버 함수 정의에서 사용된 이름에 대한 탐색과 동일한 방식으로 진행됩니다.

struct X
{
    static int x;
    static const int n = 1; // 첫 번째로 발견됨
};
int n = 2;                  // 두 번째로 발견됨
int X::x = n;               // X::n을 찾아서 X::x를 2가 아닌 1로 설정함

열거자 선언

열거자 선언 의 초기화 부분에서 사용된 이름에 대해서는, 비한정 이름 탐색이 바깥쪽 블록, 클래스, 또는 네임스페이스 범위를 검사하기 전에 동일한 열거형 내에서 이전에 선언된 열거자들이 먼저 발견됩니다.

const int RED = 7;
enum class color
{
    RED,
    GREEN = RED + 2, // RED는 color::RED를 찾으며 ::RED가 아니므로 GREEN = 2
    BLUE = ::RED + 4 // 한정된 조회는 ::RED를 찾으며 BLUE = 11
};

함수 try 블록의 핸들러

핸들러 에서 사용된 이름에 대해, 함수 try 블록 의 경우, 이름 검색은 함수 본문의 가장 바깥쪽 블록 시작 부분에서 사용된 이름인 것처럼 진행됩니다 (특히, 함수 매개변수는 보이지만, 그 가장 바깥쪽 블록에서 선언된 이름들은 보이지 않습니다)

int n = 3;          // 3번째로 발견됨
int f(int n = 2)    // 2번째로 발견됨
try
{
    int n = -1;     // 절대 발견되지 않음
}
catch(...)
{
    // int n = 1;   // 1번째로 발견됨
    assert(n == 2); // n에 대한 조회는 함수 매개변수 f를 찾음
    throw;
}

오버로드된 연산자

표현식에서 사용되는 연산자 (예: operator + a + b 에서 사용되는 경우)에 대한 탐색 규칙은 operator + ( a, b ) 와 같은 명시적 함수 호출 표현식에서 사용되는 연산자와 약간 다릅니다: 표현식을 파싱할 때 두 가지 별도의 탐색이 수행됩니다: 비멤버 연산자 오버로드에 대한 탐색과 멤버 연산자 오버로드(두 형태가 모두 허용되는 연산자의 경우)에 대한 탐색입니다. 이 집합들은 오버로드 해결 에 설명된 대로 내장 연산자 오버로드와 동등한 기준으로 병합됩니다. 명시적 함수 호출 구문이 사용되면 일반적인 비한정 이름 탐색이 수행됩니다:

struct A {};
void operator+(A, A);  // 사용자 정의 비멤버 operator+
struct B
{
    void operator+(B); // 사용자 정의 멤버 operator+
    void f();
};
A a;
void B::f() // B의 멤버 함수 정의
{
    operator+(a, a); // 오류: 멤버 함수에서의 일반 이름 검색은
                     // B의 범위에서 operator+ 선언을 찾고
                     // 거기서 멈추며 전역 범위에 도달하지 않음
    a + a; // OK: 멤버 검색은 B::operator+를 찾고, 비멤버 검색은
           // ::operator+(A, A)를 찾으며, 오버로드 해결이 ::operator+(A, A)를 선택함
}

템플릿 정의

템플릿 정의에서 사용되는 비의존적 이름(non-dependent name) 의 경우, 템플릿 정의가 검토될 때 비한정 이름 검색(unqualified name lookup)이 수행됩니다. 이 시점에서 이루어진 선언에 대한 바인딩은 인스턴스화 지점에서 보이는 선언의 영향을 받지 않습니다. 템플릿 정의에서 사용되는 의존적 이름(dependent name) 의 경우, 검색은 템플릿 인자를 알 때까지 지연되며, 이때 ADL 은 템플릿 정의 컨텍스트와 템플릿 인스턴스화 컨텍스트 모두에서 보이는 함수 선언을 검사하는 반면, 외부 링크age를 가진 (C++11 이전) 비-ADL 검색은 템플릿 정의 컨텍스트에서 보이는 함수 선언만 검사합니다(즉, 템플릿 정의 이후에 새로운 함수 선언을 추가하더라도 ADL을 통하지 않는 한 보이지 않습니다). ADL 검색이 조사하는 네임스페이스에서 외부 링크age를 가진 더 나은 매치가 다른 번역 단위에 선언되어 있거나, 해당 번역 단위들을 조사했을 때 검색이 모호했을 경우의 동작은 정의되지 않습니다. 어떤 경우든, 기본 클래스가 템플릿 매개변수에 의존하는 경우, 그 범위는 비한정 이름 검색에 의해 조사되지 않습니다(정의 지점과 인스턴스화 지점 모두에서).

void f(char); // f의 첫 번째 선언
template<class T> 
void g(T t)
{
    f(1);    // 비의존적 이름: 조회가 ::f(char)를 찾아 즉시 바인딩함
    f(T(1)); // 의존적 이름: 조회가 연기됨
    f(t);    // 의존적 이름: 조회가 연기됨
//  dd++;    // 비의존적 이름: 조회가 선언을 찾지 못함
}
enum E { e };
void f(E);   // f의 두 번째 선언
void f(int); // f의 세 번째 선언
double dd;
void h()
{
    g(e);  // g<E>를 인스턴스화하며, 이 시점에서
           // 이름 'f'의 두 번째와 세 번째 사용이
           // 조회되어 ::f(char)(조회로)와 ::f(E)(ADL로)를 찾은 후
           // 오버로드 해결이 ::f(E)를 선택함
           // 이는 f(char)를 한 번, f(E)를 두 번 호출함
    g(32); // g<int>를 인스턴스화하며, 이 시점에서
           // 이름 'f'의 두 번째와 세 번째 사용이
           // 조회되어 ::f(char)만 찾은 후
           // 오버로드 해결이 ::f(char)를 선택함
           // 이는 f(char)를 세 번 호출함
}
typedef double A;
template<class T>
class B
{
    typedef int A;
};
template<class T>
struct X : B<T>
{
    A a; // A에 대한 조회가 B<T>::A가 아닌 ::A(double)를 찾음
};

참고: 이 규칙의 이유와 함의에 대해서는 dependent name lookup rules 를 참조하십시오.

템플릿 이름

클래스 템플릿 외부의 멤버

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
CWG 490 C++98 friend 멤버 함수 선언 내 템플릿 인자의
모든 이름은 멤버 함수의 클래스 범위에서
조회되지 않았음
선언자 식별자의 템플릿 인자에
있는 이름만 제외함
CWG 514 C++98 네임스페이스 범위에서 사용된 모든 비한정 이름은
해당 범위에서 먼저 조회되었음
네임스페이스 외부에서 네임스페이스 변수 멤버를
정의하는 데 사용된 비한정 이름은 해당
네임스페이스에서 먼저 조회됨

참고문헌

  • C++23 표준 (ISO/IEC 14882:2024):
  • 6.5 이름 검색 [basic.lookup] (p: 44-45)
  • 6.5.2 멤버 이름 검색 [class.member.lookup] (p: 45-47)
  • 13.8 이름 해석 [temp.res] (p: 399-403)
  • C++20 표준(ISO/IEC 14882:2020):
  • 6.5 이름 검색 [basic.lookup] (p: 38-50)
  • 11.8 멤버 이름 검색 [class.member.lookup] (p: 283-285)
  • 13.8 이름 해석 [temp.res] (p: 385-400)
  • C++17 표준(ISO/IEC 14882:2017):
  • 6.4 이름 검색 [basic.lookup] (p: 50-63)
  • 13.2 멤버 이름 검색 [class.member.lookup] (p: 259-262)
  • 17.6 이름 해석 [temp.res] (p: 375-378)
  • C++14 표준(ISO/IEC 14882:2014):
  • 3.4 이름 검색 [basic.lookup] (페이지: 42-56)
  • 10.2 멤버 이름 검색 [class.member.lookup] (페이지: 233-236)
  • 14.6 이름 해결 [temp.res] (페이지: 346-359)
  • C++11 표준 (ISO/IEC 14882:2011):
  • 3.4 이름 검색 [basic.lookup]
  • 10.2 멤버 이름 검색 [class.member.lookup]
  • 14.6 이름 해결 [temp.res]
  • C++98 표준(ISO/IEC 14882:1998):
  • 3.4 이름 검색 [basic.lookup]
  • 10.2 멤버 이름 검색 [class.member.lookup]
  • 14.6 이름 해결 [temp.res]

참고 항목