【C++】print関数の作り方


C++でオーバーロードや可変長引数に対応した万能print関数を作ります。 これでstd::cout << 9 << std::endl;の面倒な記述ともおさらばです。

//  clang++ -std=c++11 print.cpp
#include <iostream>

namespace mc {
  namespace private_ {
    void _print() { std::cout << std::endl; }
    template<class T, class...A> void _print(const T& first, const A&... args) { std::cout << first; _print(args...); }
  }
  template<class...A> void print(const A&... args) { private_::_print(args...); }
}

using namespace mc;

int main(int argc, char *argv[]) {
  print();              // "\n"
  print("a");           // "a\n"
  print("b", "c");      // "bc\n"
  print("d", "e", "f"); // "def\n"
  print('C', 99);       // "C99\n"
  print(3.14);          // "3.14\n"
}

std::coutをラップしているため様々な型に対応出来ます。

独自クラスに対応

独自クラスの出力に対応したい場合は、以下の手順で<<演算子をオーバーロードします。

class A {
  int a = 2, b = 9;
  friend std::ostream& operator<<(std::ostream& os, const A& it);
};
std::ostream& operator<<(std::ostream& os, const A& it) { return os << it.a + it.b; }
mc::print("C", A()); // "C11\n"

カンマ区切り

カンマ区切りが欲しい場合は以下のコードも合わせてご利用ください。

namespace mc {
  namespace private_ {
    void _prints() { std::cout << std::endl; }
    template<class T, class...A> void _prints(const T& first, const A&... args) { std::cout << ", " << first; _prints(args...); }
  }
  template<class T, class...A> void prints(const T& first, const A&... args) { std::cout << first; private_::_prints(args...); }
}
prints("a");           // "a\n"
prints("b", "c");      // "b, c\n"
prints("d", "e", "f"); // "d, e, f\n"
prints('C', 99);       // "C, 99\n"
prints(3.14);          // "3.14\n"

メリークリスマス

クリスマスプレゼントですのでご自由にお使いください。

なお本ソースの利用によって問題が生じても、当局は一切関知しませんのでそのつもりで。

広告