2009-04-25 6 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

이것이 하나 소개 : STD : 벡터 A (3, 100), a_init ((A [0], A는 [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

흥미 롭 ... 여하튼 bool 공간을 낭비하지 않을 수 있습니까? – 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 인 경우) –

+0

아니요,이 항목은 3 개의 항목 벡터 (추가 요소 없음)를 표시합니다. 그러나이를 위해 매우 정교합니다. – Macke

7

A는 hackish 비트,하지만 당신이 할 수 있습니다 : 당신은 Boost's comma-separated list을 사용할 수 있습니다

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

hackish, 약간 위험합니다. 왜냐하면 여러분은 main 전에 예외를 잡을 수 없기 때문에 위험합니다.하지만이 경우에도 정확히 무엇을합니까? –

+0

@Nils : 실제로 벡터 클래스는 이런 종류의 일을 위해 배열과 결합 할 수있는 반복자 기반 ctor를 제공합니다. 훨씬 안전한 IMO. – dirkgently

8

.

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

글로벌을 사용하는 것이 아니라 사용하는 것이 좋습니다. 로컬 정적. 메인이 입력되기 전에 벡터의 초기화가 발생하기 때문에 던져진 예외는 메인에 걸리지 않습니다. 예를 들어 말해 당신은 예외 던질 수 있습니다 건설있어 유형이 다음 초기화, 생성자에 의해 throw되는 예외를 catch하지 않습니다 주요 본문에 시도/캐치

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

을, 그래서 당신을 프로그램은 즉시 죽을 것이고 아마도 디버거를 사용하여 원인을 찾을 수 없을 것입니다! answer이 제안한 기술을 이용하여 초기화 - 생성자에서 예외를 잡을

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 (...) { 
    } 
} 

다른 방법은 로컬 정전기를 사용하는 것이다.

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 (...) { 
    } 
} 
관련 문제