2016-05-24 18 views
-1

私は多数の関数をベンチマークしようとしており、タイムスタンプを一般化するマクロを定義しました。私は次のようにbenchmarking.hヘッダファイルを作っていますすべてのマクロマクロ変数の再利用

#include <chrono> 
#include <iostream> 

#define START(x) xstart = std::chrono::steady_clock::now()           
#define END(x) xend = std::chrono::steady_clock::now()           
#define TIME(x) xtime = std::chrono::duration_cast<std::chrono::nanoseconds>(xend-xstart).count() 
#define PRINT(x) std::cout << #x << "(), " << xtime << std::endl 

これは、xが、パラメータの括弧なしで、関数名に置換されています。たとえばPRINT(foobar);など しかし、xを複数回代用できると思ったので、複数の関数名に同じマクロを使用しました。 すなわち

START(foobar); 
// later... 
START(func); 

はしかし、私はエラーを取得する:

xstart’ has a previous declaration as ‘std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration\<long int, std::ratio<1l, 1000000000l> > > xstart 

私が関数を定義するためにそれを使用した後、私は、変数を再利用することはできませんように思えます。 しかし、私は決してPRINTでこのエラーを受け取りません。変数を宣言しているのですか?

私は基本的に、タイムスタンプ機能への高速な方法を考え出しています。これを達成する方法についての他の提案はすぐに歓迎します。他のマクロについて

#define START(x) x ## start = std::chrono::steady_clock::now() 

と同様:

+0

下に投票してください。 –

+0

(私の投票ではない)マクロは一般的に悪い考えです。そして、この特定のスキームは、衝突する可能性のある名前を作成するように見えます。また、 '__func__'を検索することもできます。 – MSalters

+0

ええ、私はこの正確なタスクを実行するより良い方法を知っていません。これにより、開始/終了が付加された関数名を作成できるので、少なくとも私が定義したコードの中で衝突を止めることができます。あなたが何かを持っているなら、私はより良い選択肢のために完全に開いています。ラムダは過度のように見える。 –

答えて

5

あなたはマクロトークン連結演算子##を使用する必要があります。

xstartと書くと、xはマクロ引数に置き換えられませんが、xstartはそのままになります。引数置換は、単一の識別子に対してのみ動作します。より大きな言葉の一部にすることはできません。

+0

これで私はxを "再利用"できますか? –

+0

'START(func)'で呼び出されると、結果は 'funcstart = std :: chrono :: steady_clock :: now()'になります。 'x'は引数そのもののプレースホルダです。 – owacoder

+0

素晴らしい!作品、ありがとう。これがプリプロセッサ/コンパイラ固有のものかどうかは不明ですが、マクロトークン連結演算子とオペランドの間に空白を持つ有効なプリプロセストークンを与えません。すなわち 'x ## start'エラーですが、' x ## start'は問題ありません。 –

関連する問題