web-dev-qa-db-ja.com

静的ストレージ期間の警告に対処する方法は?

私は本からC++を学ぼうとする全くの初心者です。以下のコードは期待どおりに機能し、出力を生成しますが、enginerandomIntを定義する2行に警告があります。「静的ストレージ期間を指定した「engine」の初期化では、捕まる。」

main()の中に7行目と8行目を入れると、警告は完全に消えますが、enginerandomIntgetNumberで使用できません。

警告を修正する方法がわかりません。また、おそらくより重要なこととして、main()以外のさまざまな場所でrandomIntを使用するための適切なアプローチは何ですか? main()で宣言してから、必要に応じて関数に渡すことは適切ですか?どういうわけかmain()は、これらのタイプのものを宣言するのに適切な場所のようには感じられません。

先ほどと同じような質問をしましたが、まだ理解に苦労しており、役に立つと思われる例を提供しています。

// Loosely based on Fig. 6.12: fig06_12.cpp, C++ How To Program, Ninth Edition

#include <iostream>
#include <iomanip>
#include <random>

std::default_random_engine engine( static_cast<unsigned int>( time(nullptr) ) );
std::uniform_int_distribution<unsigned int> randomInt( 1, 6 );

int getNumber();

int main() {
    for ( unsigned int counter = 1; counter <= 10; ++counter ) {
        std::cout << std::setw( 10 ) << randomInt( engine );
        if ( counter % 5 == 0 )
            std::cout << std::endl;
    }
    std::cout << getNumber() << std::endl;
    return 0;
}

int getNumber () {
    return randomInt( engine );
}

出力:

/CLionProjects/Warning/cmake-build-debug/Warning
         3         5         6         3         3
         1         4         2         4         5
2

Process finished with exit code 0
11
Timothy B.

グローバル変数の使用には問題があり、絶対に必要でない限り、それらを避けるのが一般的です。詳細については、以下を参照してください。

グローバル変数は悪いですか?

質問のタイトルは、グローバルスコープではない静的ストレージ期間変数(関数の静的ローカルなど)にも関係します。これらはそれほど問題ではありませんが、特にマルチスレッドの作業では、いくつかの頭痛の種になる可能性があります。

結論:関数をパラメーターのみに依存させ、必要な副作用をできるだけ少なくするのが最善です。これをgetNumber()関数で実行しましょう:

template <typename Distribution>
typename Distribution::result_type getNumber (
    std::default_random_engine&  random_engine,
    Distribution&                distribution) 
{
    return distribution( random_engine );
}

int main()
{
    std::default_random_engine engine( static_cast<unsigned int>( time(nullptr) ) );
    std::uniform_int_distribution<unsigned int> randomInt( 1, 6 );

    for ( unsigned int counter = 1; counter <= 10; ++counter ) {
        std::cout << std::setw( 10 ) << randomInt( engine );
        if ( counter % 5 == 0 )
            std::cout << std::endl;
    }
    std::cout << getNumber( engine, randomInt ) << std::endl;
    return 0;
}

使用している変数などのグローバル変数の初期化を遅らせる1つの方法は、get- functionsでそれらをラップすることです。

_std::default_random_engine& getEngine()
{
   // Initialized upon first call to the function.
   static std::default_random_engine engine(static_cast<unsigned int>(time(nullptr)));
   return engine;
}

std::uniform_int_distribution<unsigned int>& getRandomInt()
{ 
   // Initialized upon first call to the function.
   static std::uniform_int_distribution<unsigned int> randomInt(1, 6);
   return randomInt;
}
_

次に、変数を直接使用する代わりに、getEngine()およびgetRandomInt()を使用します。

10
R Sahu