2015-12-02 3 views
6

変数がconstであることは意味をなさない場合がありますが、スコープの後半部分でのみ発生することがあります。そのキャプチャ任意のC++のイディオムがあります定数ですが、このスコープの残りの部分だけです

void foo() { 
    int n; 
    // Do things that result in initialization of n 

    freeze n; // Imaginary construct that declares "n" const for rest of scope 

    // Later steps that depend on 'n' but do not change it 
} 

- 例えば、ブロックの最初の部分は、値を設定することもできますし、それは我々がその変数を設定し、「完了」していることが明らかであれば、残りの可読性を向上させることがありますこのパターン?もちろん、ブロックの後半部分は別の機能に移動することもできますが、移動させることなく実行できますか?

+1

「n」を生成するロジックを独自の関数にカプセル化することは、それほど意味がありませんか?そして、 'const int n = gimme_an_n();'だけです。あなたはラムダを使ってそのインラインで行うことができますが、あなたはしたいですか? – paddy

答えて

4

の代わりとして不変部分をラッピングしますラムダ、どのようにラムダに初期化部分をラップし、const intとして取得しますか?その後、変更可能な変更可能性はありませんint n

void foo() { 
    const int n = []() { ; 
     // Do things that result in initialization of n 
     return initialized_n; 
    }();  

    // Later steps that depend on 'n' but do not change it 
} 
0

@PSkocik's answer(現在削除されている)と同様の方法を使用して、匿名のラムダで目的の変数を取得し、後者を実行することができます。あなたも、このための可変引数マクロを定義することができますので、あなたは、比較的「きれいな」構文を使用して複数の変数をキャプチャすることができます:それはのすべての変数を一定にしない

#include <iostream> 

#define WITH_CONST(...) [&, __VA_ARGS__]() 
#define DO(); 

void foo() { 
    int n{1}, m{2}, z{3}; 
    WITH_CONST(n, m) // captured variables are immutable in the scope below 
    { 
     //++n; // compile-time error 
     //++m; // compile-time error 
     ++z; // z is mutable, can modify 
     std::cout << n << " " << m << " " << z << std::endl; 
    } 
    DO; 

    // n and m are not constant anymore 
    ++n; 
    ++m; 
    std::cout << n << " " << m << " " << z << std::endl; 
} 

int main() 
{ 
    foo(); 
} 

Live on Coliru

をスコープの残りの部分はですが、スコープのスコープを制御することができます。後者のスコープは、スコープの末尾まで拡張できます。

6

あなたの "フリーズ" のコードは次のようになります。

const int &refN = n; 

、その後、あなたはrefNの代わりnを使用しています。名前を変えることができます。

もっと複雑な解決策がありますが、本当に利益が痛みに見合っているかどうか自問自答する必要があります。関数が複雑であるために、nを変更したかどうか一目で分からない場合は、コードをリファクタリングする必要があります。あなたができるnを非表示にするには、例えば


、:

{ 
const int &_tmp = n; 
const int &n = _tmp; 

// rest of code 

} 

いますが、それは価値がある場合を自問する必要があります。誰がコードを読んでも、あなたが何を喫煙していたのだろうと思います。


別のオプションは、あなたの関数があるためにです:

あなたが別の関数のロジック、またはラムダオフロード
const int n = setup_n(); 

const int n = [](){ 
    // ...logic... 
    return finalized_value; 
}(); 
関連する問題