はじめに
最近競技プログラミングに興味を持ち,参加しています.また,それ以外でもプログラミングをする機会が増えてきました.
まだ全然慣れていないので,よくくだらないミスをします.
今までは,変数の中身を確認するためには,
cout << "変数名 : " << val << endl;
などといちいち書いていたのですが,これを短縮するためにマクロを定義することにしました.
数日間使用したところ,非常に重宝しているので,晒しておきます.
設定
#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); } }
使用例
以下のように変数の中身を確認する際に用いる.
#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;
}
上のプログラムの実行結果が以下である.
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()
は,マクロが複数行にまたがっているとif
やfor
内で使用する場合に不便であることから使用している.
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>
とすることで,任意の型に対して出力する関数とした.
おわりに
今回は、変数名を出力するために仕方なくマクロという形にしました。しかし、実を言うとマクロはあまり良くないらしく、本当は避けたいです。今後他の方法が見つかり次第変更しようと考えています。
本記事のマクロを使用する際は、デバッグ中だけに留めておくと良いと思います。
参考
-
https://aki-yam.hatenablog.com/entry/20081217/1229498370
- 変数名の出力方法
-
https://www.jpcert.or.jp/sc-rules/c-pre10-c.html
- 複数行マクロをdo-while{}で囲み,1行にする事