LoginSignup
13
16

More than 3 years have passed since last update.

C++のデバッグ中に便利なマクロ

Last updated at Posted at 2019-06-01

はじめに

最近競技プログラミングに興味を持ち,参加しています.また,それ以外でもプログラミングをする機会が増えてきました.
まだ全然慣れていないので,よくくだらないミスをします.
今までは,変数の中身を確認するためには,

cout << "変数名 : " << val << endl;

などといちいち書いていたのですが,これを短縮するためにマクロを定義することにしました.
数日間使用したところ,非常に重宝しているので,晒しておきます.

設定

macro
#define debug(var)  do{std::cout << #var << " : ";view(var);}while(0)
template<typename T> void view(T e){std::cout << e << std::endl;}
template<typename T> void view(const std::vector<T>& v){for(const auto& e : v){ std::cout << e << " "; } std::cout << std::endl;}
template<typename T> void view(const std::vector<std::vector<T> >& vv){ for(const auto& v : vv){ view(v); } }

使用例

以下のように変数の中身を確認する際に用いる.

main.cpp
#include <iostream>
#include <vector>
#define debug(var)  do{std::cout << #var << " : ";view(var);}while(0)
template<typename T> void view(T e){std::cout << e << std::endl;}
template<typename T> void view(const std::vector<T>& v){for(const auto& e : v){ std::cout << e << " "; } std::cout << std::endl;}
template<typename T> void view(const std::vector<std::vector<T> >& vv){ for(const auto& v : vv){ view(v); } }
using namespace std;

int main(){
  int i1 = 5;
  debug(i1);
  vector<double> v(5, 0.0);
  for(size_t i=1; i<v.size(); ++i){
    v[i] = v[i-1]+1;
  }
  debug(v);
  vector<vector<string>> vv(5, vector<string> (2, ""));
  for(size_t i=0; i<vv.size(); ++i){
    for(size_t j=0; j<vv[i].size(); ++j){
      vv[i][j] = to_string(i)+to_string(j);
    }
  }
  debug(vv);
  return 0;
}

上のプログラムの実行結果が以下である.

output
i1 : 5
v : 0 1 2 3 4 
vv : 00 01 
10 11 
20 21 
30 31 
40 41 

このように,任意の型に対して,vectorの2次元配列まで変数名と値を出力確認することができる.
2次元配列については,2行目以降は変数名分ずれるのが難点であるが.

ちょっとした解説

#define debug(var)  do{std::cout << #var << " : ";view(var);}while(0)

これがメインで,#varによって変数名を取得し,出力.view()関数は下で定義している.do-while()は,マクロが複数行にまたがっているとiffor内で使用する場合に不便であることから使用している.

template<typename T> void view(T e){std::cout << e << std::endl;}
template<typename T> void view(const std::vector<T>& v){for(const auto& e : v){ std::cout << e << " "; } std::cout << std::endl;}
template<typename T> void view(const std::vector<std::vector<T> >& vv){ for(const auto& v : vv){ view(v); } }

view()関数,template<typename T>とすることで,任意の型に対して出力する関数とした.

おわりに

今回は、変数名を出力するために仕方なくマクロという形にしました。しかし、実を言うとマクロはあまり良くないらしく、本当は避けたいです。今後他の方法が見つかり次第変更しようと考えています。
本記事のマクロを使用する際は、デバッグ中だけに留めておくと良いと思います。

参考

13
16
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
13
16