2009-04-25 10 views
7

mainの前にサイズ 'SIZE'のベクトルを初期化できるようにします。通常、私はC++のmain()の前のベクトルを初期化する

static vector<int> myVector(4,100); 

int main() { 

    // Here I have a vector of size 4 with all the entries equal to 100 

} 

を行うだろう。しかし、問題は、私は特定の価値があるとベクトルの最初の項目を初期化したい、と別の値に他のだろうということです。

これを行う簡単な方法はありますか?

+0

何本約1:のstd ::ベクトル(3、100)、&a_init(([0]、[1] 99 = 98 = A))。それは "98,99,100"に等しくなります:) –

+1

好奇心の外に、なぜあなたはそれを必要としますか? –

答えて

6

をここで代替ソリューションです:

#include <vector>     
static std::vector<int> myVector(4,100); 

bool init() 
{ 
    myVector[0] = 42;  
    return true; 
} 

bool initresult = init(); 

int main()     
{ 
    ; 
} 
+0

面白い...どうにかしてブール空間を無駄にすることはできないのですか? – Unknown

+0

はい、実際はそうではありません。あなたはどこかにinitcallを埋め込むことができますが、それはそれを隠すでしょう:int somevalue =(init()、42); –

+0

staticは、 "内部"リンケージ(つまり翻訳ユニット内のみ)のためのノーティファイヤとして推奨されていません。代わりに匿名の名前空間を使用してください。 – Macke

20

この試してみてください。また

static int init[] = { 1, 2, 3 }; 
static vector<int> vi(init, init + sizeof init/sizeof init[ 0 ]); 

を、(あなたが関数内で初期化したい場合)std::generateを参照してください。

+1

これは最も明白な方法であるだけでなく、最速で明瞭な方法です。 +1(少なくとも他のアイテムがすべてゼロの場合) –

+0

いいえ、これは3つのアイテムベクトル(余分な要素なし)を与えますが、それはかなりきれいです。 – Macke

7

ビットハックが、あなたはこれを行うことができます:

struct MyInitializer { 
    MyInitializer() { 
     myVector[0]=100; 
     //... 
    } 
} myInitializer; // This object gets constructed before main() 
+0

hackish、少し危険です。メインの前に例外をキャッチすることはできませんが、まさにこれらのケースでも私は何をしますか。 –

+0

@Nils:実際には、ベクトルクラスは、ちょうどこのようなことのために配列と結合できる反復子ベースのctorを提供します。はるかに安全なIMO。 – dirkgently

9

それとも、関数を作成して、それを呼び出す:

std::vector<int> init() 
{ 
    ... 
} 

static std::vector<int> myvec = init() 

ビットを非効率的かもしれないが、それは今、あなたには関係ないかもしれませんし、C++ 0xで、それは非常に高速になります移動。

あなたは(C++ 03およびそれ以前のための)コピーを避けたい場合は、スマートポインタを使用します。

std::vector<int>* init() { 
    return new std::vector<int>(42); 
} 

static boost::scoped_ptr<std::vector<int>> myvec(init()); 
0

クラスでそれをラップ:

class SpecialVector 
{ 
    public: 
    SpecialVector() 
    { 
     myVector[0] = 1; 
     myVector[1] = 4; 
     // etc. 
    } 
    const vector<int> & GetVector() const 
    { 
     return myVector; 
    } 
    private: 
    vector<int> myVector; 
}; 
static SpecialVector SpVec; 

int main() { 
} 
+0

なぜなぜ..... ..... –

+0

グローバルな静的は悪い....例外をキャッチする方法はありません、valgrindはアプリケーションの終了時に例外がある場合、デバッグするのがリークだと思います! –

9

C++ 0xのがちょうど集合体のように、標準コンテナの初期化子リストを許可します。

std::vector<int> bottles_of_beer_on_the_wall = {100, 99, 98, 97}; 

明らかに標準ではありませんが、GCC 4.4からサポートされていると思われます。私はMSVCのドキュメントを見つけることができませんが、Herb Sutterは彼らのC++ 0xサポートが委員会より先行していると言っています...

3

グローバルを使用するのではなく、ローカル静的。メインが入力される前にベクタの初期化が行われるため、スローされた例外はmainによって捕捉されません。あなたはそれが構築されていますタイプが例外をスローすることが持っている、たとえば言う:次の初期化のために

class A { 
public: 
    A() { 
    // ... code that might throw an exception 
    } 
}; 

、メインの体内でのtry/catchはコンストラクタによってスローされた例外をキャッチし、ので、あなたはありませんプログラムはただちに終了し、おそらくデバッガを使って原因を突き止めることさえできません。

std::Vector<A> v(5, A()); // May throw an exception here not caught by main 

int main() { 
    try { 
    // Exception for 'v' not handled here. 
    } 
    catch (...) { 
    } 
} 

コンストラクタから例外をキャッチする別のアプローチは、ローカル静的使用することである - このanswerによって提案手法を用いて初期化されます。

std::Vector<A> init(); // Returns a vector appropriately initialized 

std::vector<A> & getV() { 
    static std::vector<A> cache = init(); 
    return cache; 
} 

int main() { 
    try { 
    getV().at[0]; // First call to getV - so initialization occurs here! 
    } 
    catch (...) { 
    } 
} 
関連する問題