【C++】特定クラスを個別にusingする方法【脱 using namespace std】

std::coutstd::string等の省略記法(cout, string)を個別に利用可能にする方法を紹介します。型指定が可能なstd::vectorstd::map等のテンプレート・クラスも個別に宣言出来ます。

ちなみにusing namespace std;を利用すればstd内の全ての型が一括で利用が可能になりますが、若干危険ですので(参考:using namespace std; は危険)、今回個別に宣言する方法を紹介したいと思った次第です。

変数・関数

using宣言(using declaration)によって、特定のメンバを利用可能にすることが出来ます。

using std::cout;
using std::endl;
// Before
std::cout << 123 << std::endl;
// After
cout << 123 << endl;

関数の場合も同じ方法を用います

using std::sort;
using std::max;
using std::move;

クラス

std::stringクラスの場合は変数の時と同様の記法が使えます。

std::vector<std::string>等のテンプレートクラスの場合はエイリアス宣言(alias declaration)による別名での宣言が必要です。

using std::string;
using String = std::string; // 別名も付けられる

using strings = std::vector<std::string>;
strings vec = {string("A"), String("B")};

テンプレートクラス

型指定が可能なテンプレートクラス(std::array<T>, shared_ptr<T>等)をエイリアステンプレート(alias templates)により別名で定義する方法です。

template<typename T>
using vector = std::vector<T>;
vector<int> vec = {1, 2, 3};

usingの活用方法について

これらのusing宣言/エイリアス宣言/エイリアステンプレートによる個別の宣言/定義をどのタイミングで行うべきかに関してですが、using namespace stdの代替として使うのであれば、グローバル空間の汚染を慎重に考慮した上で、従来どおりmain関数の外や実装ファイルの冒頭で利用するのもよいと思います。

ただ一番のオススメは必要になった時に局所的に定義する方法です。 特に頻繁に使われないようなクラスではこちらの方法がベストです。

namespace mylib {
   // 名前空間で個別に宣言(mylib内限定で利用可能)
   using std::cout;
   
   void test() {
      // 関数内で個別に宣言
      using std::endl;
      cout << 1 << endl;
      cout << 2 << endl;
   }
   
   struct String {
      // クラス内で個別に定義
      using string = std::string;
      
      string _str;
      String(const char* str) : _str(str) {}
      void print() { cout << _str << std::endl; }
   };
   
   // 無名名前空間だと同一名前空間に汚染するので注意
   namespace { using std::endl; }
   // 侵食したendlが使えてしまう
   void hazard() { std::cout << endl; }
}

参考:using namespace std; は危険 ─ # 限定的にusing namespace stdする

より詳しい説明や注意点は上記ページで解説していますので参考にしてください。

広告