4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C++ お行儀の悪い標準入力

Posted at

はじめに

C++で競技プログラミングをしていてこう思ったことはありませんか?

「 標準入出力でシフト演算子 >> << を書くのだるすぎ!!!!!! 」

自分はいつも思っています

お行儀が悪いですが簡単にできる対処法をいくつか考えてみました

本文

1. カンマ演算子のオーバーロード

>> って打つのがだるいなら , ならマシだろ という安直な発想です

つまり

std::cin >> a >> b >> c;

としていたのを

std::cin >> a, b, c;

みたいに書こうということです

実装は簡単で,

# include <iostream>

template <typename T>
std::istream &operator,(std::istream &is, T &x){
  return is >> x;
}

int main(){
  int a;
  std::string s;

  std::cin >> a, s;
}

こんな感じに適当にオーバーロードすればいいです

2. 可変引数の関数

こっちのほうがまだマシなはずです

可変引数テンプレート を利用して, 可変長の引数を受け取れる関数を作ってみましょう

まず, 再帰呼び出しを利用した方法として

# include <iostream>

template <typename T>
void input(T &x){
  std::cin >> x;
}

template <typename T, typename... Args>
void input(T &x, Args&&... args){
  std::cin >> x;
  input(args...);
}


int main(){
  int a;
  std::string s;

  input(a, s);
}

こんな感じに書くことができます

二つ目以降の引数はすべて args に突っ込まれるわけですね


さて, これはこれでよさそうですが, C++17 以降ならもっと簡単に書くことができます

畳み込み式 という言語機能が追加されているため, これを利用します

するとどうなるのかというと,

# include <iostream>

template <typename... Args>
void input(Args&&... args){
  (std::cin >> ... >> args);
}

int main(){
  int a;
  std::string s;

  input(a, s);
}

これだけでできます

これは 二項左畳み込み というやつです 詳しくは上のリンクに書いてあるので, ぜひ読んでみてください

おわりに

いかがでしたか?

自分は競技プログラミングでいつもこの最後に書いた関数を使っています

もし気に入ったモノがあれば使ってみてください (ここにさらにマクロを使ったりしても楽しそうです)

そうでなくても, せっかく cpprefjp という神サイトがあるのでこういった言語機能を調べてみるのもいいんじゃないかと思います

ありがとうございました

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?