2017-07-15 3 views
0

ローカル関数定義を使用してコードブロックをN回実行すると、C#の並列バージョンのように動作しますが、同じスコープ内で2つ以上を使用すると、f関数の多重定義エラーが発生します。 f1、f2、f3などの関数名を段階的に変更するにはどうしたらよいですか?C++:どのように同じ範囲で複数回parallel-forマクロを使用できますか?


定義:

#ifndef PARALLEL_FOR 
#define PARALLEL_FOR(N,O) \ 
         struct LocalClass               \ 
         {                   \ 
          void operator()(int i) const O          \ 
         } f;                  \ 
         std::thread threads[N];              \ 
         for(int loopCounterI=0; loopCounterI<N; loopCounterI++)      \ 
         {                   \ 
          threads[loopCounterI]=std::thread(f,loopCounterI);      \ 
         }                   \ 
         for(int loopCounterI=0; loopCounterI<N; loopCounterI++)      \ 
         {                   \ 
          threads[loopCounterI].join();           \ 
         }                   \ 

#endif 

使用法:

PARALLEL_FOR(
     5, 
     {std::cout<<100*i<<std::endl;} 
); 

出力:

0 
300 
200 
100 
400 

は、通常、その結果としての通話が、WHAのために解決するだろう{\}\を追加私は並行してネストされていますか?

+0

あなたがマクロ文字列の連結を使用することができ、IEを、 '##'。だから 'LocalClass ## Number'。 –

+0

しかし、同じマクロを2回使用してNumberをインクリメントすることはできません。たぶん私は間違っています? –

+0

単一の他のパラメータを渡すか、以前に実行されたすべてのインデックスを追跡するために複雑で圧倒的な方法を使用します。下に投稿された回答のように、カウントを渡すだけです。 –

答えて

2

私にとっては理想的な解決策ではありませんが、##を使用してマクロ内の文字列を連結できます。あなたのコードで以下を実行してください

#ifndef PARALLEL_FOR 
#define PARALLEL_FOR(N,O,usageInd) \ 
        struct LocalClass##usageInd               \ 
        {                   \ 
         void operator()(int i) const O          \ 
        } f##usageInd;                  \ 
        std::thread threads[N];              \ 
        for(int loopCounterI=0; loopCounterI<N; loopCounterI++)      \ 
        {                   \ 
         threads[loopCounterI]=std::thread(f##usageInd,loopCounterI);      \ 
        }                   \ 
        for(int loopCounterI=0; loopCounterI<N; loopCounterI++)      \ 
        {                   \ 
         threads[loopCounterI].join();           \ 
        }                   \ 

#endif 

それぞれの使用法についてインデックスを渡すことはあなた次第です。

+0

だから私はそれを "ネストループの深さ"と呼ぶことができます。 –

+0

@huseyintugrulbuyukisik私はあなたが何を意味するか分からないが、命名は本当に重要ではない。 – Daniel

5

一意のIDを渡す代わりに、__LINE__を使用できます。

しかし、醜いマクロの代わりに、ラムダで関数を使用してみませんか?

このように使用
template <int N, class F> 
void parallel_for(F f) { 
    std::thread threads[N]; // or std::array<std::thread, N> threads; 

    for(int loopCounterI=0; loopCounterI<N; loopCounterI++) { 
     threads[loopCounterI]=std::thread(f,loopCounterI); 
    } 
    for(int loopCounterI=0; loopCounterI<N; loopCounterI++) { 
     threads[loopCounterI].join(); 
    } 
} 

parallel_for<5>([] (int i) { 
    std::cout<<100*i<<std::endl; 
}); 

ラムダは、必要な変数をキャプチャすることができます。

int j = ...; 
parallel_for<5>([j] (int i) { 
    std::cout<<100*(i+j)<<std::endl; 
}); 
+1

これはマクロを使用するよりも優れています。このような醜いマクロを使用するよりも、これを行う関数を使用するほうがはるかにエレガントです – Daniel

関連する問題