using
読み:ユージング
外語:using
C++の予約語の一つ。
概要
他の名前空間で定義されている名前を輸入する。
C++11では型エイリアスを定義する機能が追加された。これにより、templateを含めた別名定義にも使用できるようになり、旧来のtypedefを置き換える機能を有するようになった。
用例
名前空間
標準の名前空間を指定する。using指令とusing宣言が存在する。
using指令
よく使われるのはstd名前空間をグローバルとして扱う次である。
using namespace std;
ブロックスコープ{}内で使えばそのブロックスコープに限って機能するが、グローバル領域でも可能である。
using namespace std;は多くの場合、プログラムの先頭部分のグローバル領域に書いて使用されている。こうすることで、std::string であるとか、std::cout << hoge << std::endl; のようにいちいちstdを書かずとも、string あるいは cout << hoge << endl; のようにして使うことができるようになる。
但し、stdをグローバルにしてしまうこの手法については古くより賛否両論がある。
using宣言
指定したシンボルを、そのスコープ内に追加する機能である。
using指令とは異なりグローバル領域では使用できず、必ず何らかのブロックスコープで使用する必要があるほか、そのブロックスコープを抜けると宣言は無効になる。
namespace hoge {
int a = 1;
int b = 2;
}
int main() {
using hoge::a; // ←これがusing宣言
int x = a; // OK
int y = b; // エラー
return 0;
}
using指令とは異なり名前空間全体を取り込むのではなく、指定したシンボルだけを取り込むため、影響は最小限で済ますことができる。
std名前空間の中にあるももでも書き方は同様で、次のように必要なものだけを書くという方法が利用できる。
using std::cout;
using std::endl;
using std::string;
型エイリアス
C++11ことISO/IEC 14882:2011より、typedefの代替となる型エイリアスの記述が可能となった。つまり、別名定義をusingで行なうことが出来る。
例えば、Javaの文字列はStringでJavaとC++並行開発ではついうっかり書き間違えたりするが、次のようにすると解決する可能性があるかもしれないし、ないかも知れない。
using String = std::string;
typedefと違って順番や構文が自然であり、見た目も分かり易い。
std::stringは例外だが、これは元々はテンプレートクラスである。このような特殊なテンプレートクラス以外(例えばstd::vector<>など)をusingする場合は、using宣言は使えず、型エイリアスを使用する必要がある。
using vstring = std::vector<std::string>;
テンプレートクラス
型エイリアスの応用となるが、C++11以降ではテンプレートクラスを定義するさいに、usingを用いた別名定義が可能となった。
using指令は使わず必要最小限のusing宣言や型エイリアスで済まそうとした場合には必要となる手法である。
例えば、型が指定できるstd::vectorは、次のようなテンプレートクラスを定義することで、スコープ内に追加することが可能である。
template<typename T>
using vector = std::vector<T>;
名前空間の汚染を防ぎ、意図せぬバグを作り込まずに済むような言語仕様の改良となっている。
関連する用語
再検索