using 宣言using declaration

宣言は、 using using 宣言が表示される宣言領域に名前を導入します。The using declaration introduces a name into the declarative region in which the using declaration appears.

構文Syntax

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

パラメーターParameters

nested-name-指定子 スコープ解決演算子によって終了された名前空間、クラス、または列挙体の名前とスコープ解決演算子 (::) のシーケンス。nested-name-specifier A sequence of namespace, class, or enumeration names and scope resolution operators (::), terminated by a scope resolution operator. 単一のスコープ解決演算子を使用して、グローバル名前空間から名前を導入することができます。A single scope resolution operator may be used to introduce a name from the global namespace. キーワード typename は省略可能であり、基底クラスからクラステンプレートに導入された場合に依存名を解決するために使用できます。The keyword typename is optional and may be used to resolve dependent names when introduced into a class template from a base class.

修飾なしの id 修飾されていない id 式。識別子、オーバーロードされた演算子名、ユーザー定義のリテラル演算子または変換関数の名前、クラスデストラクター名、テンプレート名、および引数リストを指定できます。unqualified-id An unqualified id-expression, which may be an identifier, an overloaded operator name, a user-defined literal operator or conversion function name, a class destructor name, or a template name and argument list.

宣言子リスト[ typename ]入れ子になった名前指定子 宣言子のコンマ区切りのリスト。オプションで省略記号を指定します。declarator-list A comma-separated list of [typename] nested-name-specifier unqualified-id declarators, followed optionally by an ellipsis.

解説Remarks

Using 宣言では、他の場所で宣言されたエンティティのシノニムとして非修飾名が導入されます。A using declaration introduces an unqualified name as a synonym for an entity declared elsewhere. これにより、特定の名前空間の単一の名前を、それが出現する宣言領域で明示的に修飾することなく使用できます。It allows a single name from a specific namespace to be used without explicit qualification in the declaration region in which it appears. これは、 using ディレクティブとは異なり、名前空間内の すべて の名前を修飾なしで使用できます。This is in contrast to the using directive, which allows all the names in a namespace to be used without qualification. キーワードは、 using 型のエイリアスにも使用されます。The using keyword is also used for type aliases.

例: using クラスフィールド内の宣言Example: using declaration in class field

using 宣言は、クラス定義で使用できます。A using declaration can be used in a class definition.

// 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 メンバーを宣言する宣言Example: using declaration to declare a member

メンバーの宣言に使用する場合、using 宣言は基底クラスのメンバーを参照する必要があります。When used to declare a member, a using declaration must refer to a member of a base class.

// 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 明示的修飾子を使用した宣言Example: using declaration with explicit qualification

Using 宣言を使用して宣言されたメンバーは、明示的な修飾を使用して参照できます。Members declared by using a using declaration can be referenced by using explicit qualification. :: プレフィックスは、グローバル名前空間を参照します。The :: prefix refers to the global namespace.

// 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 宣言のシノニムとエイリアスExample: using declaration synonyms and aliases

using 宣言を行うと、宣言によって作成されるシノニムは、using 宣言の時点で有効である定義のみを参照します。When a using declaration is made, the synonym created by the declaration refers only to definitions that are valid at the point of the using declaration. using 宣言の後で名前空間に追加される定義は、無効なシノニムです。Definitions added to a namespace after the using declaration are not valid synonyms.

宣言によって定義さ using れる名前は、元の名前のエイリアスです。A name defined by a using declaration is an alias for its original name. using 宣言は元の宣言の型、リンケージ、またはその他の属性には影響しません。It does not affect the type, linkage or other attributes of the original declaration.

// 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 宣言Example: Local declarations and using declarations

名前空間内の関数では、1 つの名前のローカル宣言と using 宣言が同じスコープ内にある場合、それらはすべて同じエンティティ、つまり関数を参照している必要があります。With respect to functions in namespaces, if a set of local declarations and using declarations for a single name are given in a declarative region, they must all refer to the same entity, or they must all refer to functions.

// 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 ステートメントにより、2 つ目の int ig() 関数で宣言されます。In the example above, the using B::i statement causes a second int i to be declared in the g() function. using B::f 内に定義された関数名に異なるパラメーター型があるため、f(char) ステートメントと B::f 関数は競合しません。The using B::f statement does not conflict with the f(char) function because the function names introduced by B::f have different parameter types.

例: ローカル関数の宣言と using 宣言Example: Local function declarations and using declarations

ローカル関数宣言は、using 宣言で定義された関数と同じ名前および型を含むことはできません。A local function declaration cannot have the same name and type as a function introduced by using declaration. 次に例を示します。For example:

// 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 宣言と継承Example: using declaration and inheritance

継承では、using 宣言で基底クラスの名前を派生クラスのスコープ内に定義すると、派生クラスのメンバー関数によって、基底クラスで同じ名前と引数の型を持つ仮想メンバー関数がオーバーライドされます。With respect to inheritance, when a using declaration introduces a name from a base class into a derived class scope, member functions in the derived class override virtual member functions with the same name and argument types in the base class.

// 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 宣言アクセシビリティExample: using declaration accessibility

using 宣言で定義された名前のすべてのインスタンスはアクセス可能である必要があります。All instances of a name mentioned in a using declaration must be accessible. 特に、派生クラスが基底クラスのメンバーにアクセスするために using 宣言を使用する場合は、そのメンバー名がアクセス可能である必要があります。In particular, if a derived class uses a using declaration to access a member of a base class, the member name must be accessible. 名前がオーバーロードされたメンバー関数の名前である場合、その名前のすべての関数にアクセス可能である必要があります。If the name is that of an overloaded member function, then all functions named must be accessible.

メンバーのアクセシビリティの詳細については、「 メンバー Access Control」を参照してください。For more information on accessibility of members, see 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
};

関連項目See also

名前空間Namespaces
キーワードKeywords