선언 사용

선언은 using using 선언이 나타나는 선언적 영역에 이름을 도입합니다.

구문

using [typename] nested-name-specifier unqualified-id ;
using declarator-list ;

매개 변수

nested-name-specifier 네임스페이스, 클래스 또는 열거형 이름 및 범위 확인 연산자(::), 범위 확인 연산자에 의해 종료되는 시퀀스입니다. 단일 범위 확인 연산자를 사용하여 전역 네임스페이스의 이름을 도입할 수 있습니다. 키워드(keyword) typename 선택 사항이며 기본 클래스에서 클래스 템플릿에 도입될 때 종속 이름을 확인하는 데 사용할 수 있습니다.

unqualified-id 식별자, 오버로드된 연산자 이름, 사용자 정의 리터럴 연산자 또는 변환 함수 이름, 클래스 소멸자 이름 또는 템플릿 이름 및 인수 목록일 수 있는 정규화되지 않은 id 식입니다.

declarator-list [typename] nested-name-specifier unqualified-id 선언자의쉼표로 구분된 목록과 선택적으로 줄임표가 잇습니다.

설명

using 선언은 다른 곳에서 선언된 엔터티의 동의어로 정규화되지 않은 이름을 도입합니다. 표시되는 선언 영역에서 명시적 정규화 없이 특정 네임스페이스의 단일 이름을 사용할 수 있습니다. 이는 네임스페이스의 모든 이름을 한정 없이 사용할 수 있는 using 지시문과는 대조적입니다. using 키워드(keyword) 형식 별칭에도 사용됩니다.

예제: using 클래스 필드의 선언

using 선언은 클래스 정의에서 사용할 수 있습니다.

// using_declaration1.cpp
#include <stdio.h>
class B {
public:
   void f(char) {
      printf_s("In B::f()\n");
   }

   void g(char) {
      printf_s("In B::g()\n");
   }
};

class D : B {
public:
   using B::f;    // B::f(char) is now visible as D::f(char)
   using B::g;    // B::g(char) is now visible as D::g(char)
   void f(int) {
      printf_s("In D::f()\n");
      f('c');     // Invokes B::f(char) instead of recursing
   }

   void g(int) {
      printf_s("In D::g()\n");
      g('c');     // Invokes B::g(char) instead of recursing
   }
};

int main() {
   D myD;
   myD.f(1);
   myD.g('a');
}
In D::f()
In B::f()
In B::g()

예: using 멤버를 선언하는 선언

멤버를 선언하는 데 사용되는 경우 using 선언은 기본 클래스의 멤버를 참조해야 합니다.

// using_declaration2.cpp
#include <stdio.h>

class B {
public:
   void f(char) {
      printf_s("In B::f()\n");
   }

   void g(char) {
      printf_s("In B::g()\n");
   }
};

class C {
public:
   int g();
};

class D2 : public B {
public:
   using B::f;   // ok: B is a base of D2
   // using C::g;   // error: C isn't a base of D2
};

int main() {
   D2 MyD2;
   MyD2.f('a');
}
In B::f()

예: using 명시적 정규화가 있는 선언

using 선언을 사용하여 선언된 멤버는 명시적 한정을 사용하여 참조할 수 있습니다. :: 접두사는 전역 네임스페이스를 참조합니다.

// using_declaration3.cpp
#include <stdio.h>

void f() {
   printf_s("In f\n");
}

namespace A {
   void g() {
      printf_s("In A::g\n");
   }
}

namespace X {
   using ::f;   // global f is also visible as X::f
   using A::g;   // A's g is now visible as X::g
}

void h() {
   printf_s("In h\n");
   X::f();   // calls ::f
   X::g();   // calls A::g
}

int main() {
   h();
}
In h
In f
In A::g

예: using 선언 동의어 및 별칭

using 선언이 만들어지면 선언에서 만든 동의어는 using 선언의 지점에서 유효한 정의만 참조합니다. using 선언 후에 네임스페이스에 추가된 정의는 유효한 동의어가 아닙니다.

선언으로 using 정의된 이름은 원래 이름의 별칭입니다. 원래 선언의 형식, 링크 또는 기타 특성에는 영향을 주지 않습니다.

// post_declaration_namespace_additions.cpp
// compile with: /c
namespace A {
   void f(int) {}
}

using A::f;   // f is a synonym for A::f(int) only

namespace A {
   void f(char) {}
}

void f() {
   f('a');   // refers to A::f(int), even though A::f(char) exists
}

void b() {
   using A::f;   // refers to A::f(int) AND A::f(char)
   f('a');   // calls A::f(char);
}

예: 로컬 선언 및 using 선언

네임스페이스의 함수와 관련하여 선언적 지역에 로컬 선언 집합과 단일 이름에 대한 선언을 사용하는 경우 모두 동일한 엔터티를 참조해야 하거나 모두 함수를 참조해야 합니다.

// functions_in_namespaces1.cpp
// C2874 expected
namespace B {
    int i;
    void f(int);
    void f(double);
}

void g() {
    int i;
    using B::i;   // error: i declared twice
    void f(char);
    using B::f;   // ok: each f is a function
}

위의 예제에서 이 문은 using B::i 함수에서 g() 두 번째 int i 문을 선언합니다. 이 문은 using B::f 매개 변수 형식이 f(char) 다르기 때문에 함수 B::f 와 충돌하지 않습니다.

예: 로컬 함수 선언 및 using 선언

로컬 함수 선언은 선언을 사용하여 도입된 함수와 동일한 이름과 형식을 가질 수 없습니다. 예시:

// functions_in_namespaces2.cpp
// C2668 expected
namespace B {
    void f(int);
    void f(double);
}

namespace C {
    void f(int);
    void f(double);
    void f(char);
}

void h() {
    using B::f;          // introduces B::f(int) and B::f(double)
    using C::f;          // C::f(int), C::f(double), and C::f(char)
    f('h');              // calls C::f(char)
    f(1);                // C2668 ambiguous: B::f(int) or C::f(int)?
    void f(int);         // C2883 conflicts with B::f(int) and C::f(int)
}

예: using 선언 및 상속

상속과 관련하여 using 선언에서 기본 클래스의 이름을 파생 클래스 범위로 도입하는 경우 파생 클래스의 멤버 함수는 기본 클래스의 이름과 인수 형식이 같은 가상 멤버 함수를 재정의합니다.

// using_declaration_inheritance1.cpp
#include <stdio.h>
struct B {
   virtual void f(int) {
      printf_s("In B::f(int)\n");
   }

   virtual void f(char) {
      printf_s("In B::f(char)\n");
   }

   void g(int) {
      printf_s("In B::g\n");
   }

   void h(int);
};

struct D : B {
   using B::f;
   void f(int) {   // ok: D::f(int) overrides B::f(int)
      printf_s("In D::f(int)\n");
   }

   using B::g;
   void g(char) {   // ok: there is no B::g(char)
      printf_s("In D::g(char)\n");
   }

   using B::h;
   void h(int) {}   // Note: D::h(int) hides non-virtual B::h(int)
};

void f(D* pd) {
   pd->f(1);     // calls D::f(int)
   pd->f('a');   // calls B::f(char)
   pd->g(1);     // calls B::g(int)
   pd->g('a');   // calls D::g(char)
}

int main() {
   D * myd = new D();
   f(myd);
}
In D::f(int)
In B::f(char)
In B::g
In D::g(char)

예: using 선언 접근성

using 선언에 멘션 이름의 모든 인스턴스에 액세스할 수 있어야 합니다. 특히 파생 클래스가 using 선언을 사용하여 기본 클래스의 멤버에 액세스하는 경우 멤버 이름에 액세스할 수 있어야 합니다. 이름이 오버로드된 멤버 함수의 이름인 경우 명명된 모든 함수에 액세스할 수 있어야 합니다.

멤버의 접근성에 대한 자세한 내용은 Member-Access Control을 참조하세요.

// using_declaration_inheritance2.cpp
// C2876 expected
class A {
private:
   void f(char);
public:
   void f(int);
protected:
   void g();
};

class B : public A {
   using A::f;   // C2876: A::f(char) is inaccessible
public:
   using A::g;   // B::g is a public synonym for A::g
};

참고 항목

네임스페이스
키워드