2017-03-03 19 views
1

呼び出し元ごとにフル機能の複数のコピーを作成する必要なく、関数呼び出し元によって実行されるものを指示するいくつかのキーワードを使用して、複数のC++関数コンテンツをコンパイルできますか?呼び出し元に基づくC++関数の内容

今のところ解決策は、呼び出し元に応じて関数と文を実行するためのパラメータを使用することです。

V sol::compare(uchar start_lev, V *a , V *b){ 
solMutex.lock(); // not needed by all callers 
for(auto lev:solVec){ 
switch (lev.group){ 
case a: 
dontRemove=0; 
val++; // not used by all callers 
return something; 
case b: 
val++; //not used by all callers 
return something; 
case c: 
     etc... 
} 
#ifdef QT_DEBUG // not needed by all callers 

ことができる単一の機能をコーディングし、いくつかのキーワードを追加し、それが別の発信者に応じて、機能の未使用部分のオーバーヘッドなしに、いくつかのバリエーションをコンパイルする場合。

+0

これは、関数呼び出しに応じて関数を実行するための関数のパラメータです。さもなければ、関数はそれを呼び出した人を何とか魔法のように判断する手段がありません。 –

+2

テンプレートをお探しですか?あなたが書きたいと思うコードの簡潔なサンプルを私達に与えてください。 –

+0

プログラムのパフォーマンスを強化する部分で、呼び出し元に応じて4つの変更されたバージョンの関数を使用します。 – Flow

答えて

1

私は最後に、マクロとの契約が何であるかわからないんだけど、あなたはこのようにやりたいことができます。

template <bool do_lock, bool do_increment> 
V sol::compare(uchar start_lev, V *a , V *b){ 
    if (do_lock) solMutex.lock(); // not needed by all callers 
    for(auto lev:solVec){ 
    switch (lev.group){ 
    case a: 
     dontRemove=0; 
     if (do_increment) val++; // not used by all callers 
     return something; 
    case b: 
     if (do_increment) val++; //not used by all callers 
     return something; 
    case c: 
     etc... 
} 

これを呼び出すには、あなたがして

auto v = sol::compare<false, false>(....); 
を行うだろう

特定の発信者がそれを必要とするかどうかに応じて、これらのブール値を変更します。コンパイラがブーリアンの組み合わせごとに異なる関数を生成しているので、コンパイル時に入力するブール値を知るには、があることに注意してください。ブール値はコンパイル時に分かっているので、ブールが偽であれば、それらのブランチは任意のコンパイラによってデッドコードとして単純に整理されます。

+0

情報をいただきありがとうございます。テンプレートは、コードを簡単に保守するための良い方法です。 – Flow

1

その後、コメントにいくつかのアイデアのスケッチを投稿しました。

V sol::compare(uchar start_lev, V *a , V *b) { 
    solMutex.lock(); // not needed by all callers 
    for(auto lev:solVec){ 
     switch (lev.group){ 
      case a: 
       dontRemove=0; 
       val++; // not used by all callers 
       return something; 
      case b: 
       val++; //not used by all callers 
       return something; 
      case c: 
       ///etc... 
     } 
     #ifdef QT_DEBUG // not needed by all callers 
} 

プリプロセッサの場合、コードワイズに行うことはあまりありません。

これ以外にもブーリアンを使用できます。代わりがあります。

他のパターンについては、共通性と相違点を分けることができます。 例えば、solMutexは、いくつかの架空のsol通話のメンバ変数であるならば、我々はlockingSol

class sol 
{ 
public: 
    V sol::compare(uchar start_lev, V *a , V *b); 
     for(auto lev:solVec){ 
      //etc 
     } 
    } 
}; 


class lockingSol 
{ 
public: 
    V compare(uchar start_lev, V *a , V *b) 
    { 
     solMutex.lock(); 
     return sol_.compare(start_lev, a, b); 
    } 

private: 
    mutex solMutex; 
    sol sol_; 
}; 

を持つことができますこれはnonlockingSolsolMutex.lock();を呼び出してから、sol_のメソッドを呼び出すことができます。

テンプレートとstragey desginパターンは、振る舞いを切り替える方法を提供します。

また、ファンクタまたはラムダを送信して、アルゴリズムの途中で何が起きるかを尋ねることもできます。標準ライブラリiteselfは、これの多くの例を示しています。例えば

は何かの上に

template< class RandomIt, class Compare > 
void sort(RandomIt first, RandomIt last, Compare comp); 

この繰り返し処理を考慮し、呼び出し側は、反復内で何が起こるかを変化させるためにCompare機能に送信します。

関連する問題