2009-04-25 12 views
7

में मुख्य() से पहले एक वेक्टर शुरू करना मैं मुख्य से पहले आकार 'SIZE' के वेक्टर को प्रारंभ करने में सक्षम होना चाहता हूं। आम तौर पर मैंसी ++

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

int main() { 

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

} 

करना होगा लेकिन समस्या यह है कि मैं वेक्टर के पहले आइटम प्रारंभ करने के लिए एक निश्चित मूल्य का होना चाहते हैं, और एक अन्य मूल्य के लिए अन्य है।

क्या ऐसा करने का कोई आसान तरीका है? (यदि आप एक समारोह के भीतर प्रारंभ करना चाहते हैं)

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

इसके अलावा, std::generate देखें:

+0

के बारे में यह एक क्या: std :: वेक्टर एक (3, 100), और a_init ((क [0] 98 =, एक [1] = 99, एक)); यह "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

यह भी ध्यान रखें कि स्थैतिक को "आंतरिक" लिंक के लिए नोटिफ़ायर के रूप में बहिष्कृत किया गया है (यानी केवल अनुवाद इकाई के भीतर)। इसके बजाए एक अज्ञात नेमस्पेस का प्रयोग करें। – Macke

20

इस प्रयास करें।

+1

यह न केवल सबसे स्पष्ट तरीका है, बल्कि सबसे तेज़ और स्पष्ट तरीका भी है। +1 (कम से कम यदि अन्य आइटम शून्य हैं) –

+0

नहीं, यह 3 आइटम वेक्टर (कोई अतिरिक्त तत्व नहीं) देगा, लेकिन इसके लिए, यह बहुत साफ है। – Macke

7

एक hackish सा है, लेकिन आप ऐसा कर सकता है:

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

हैकिश, और थोड़ा खतरनाक है क्योंकि आप मुख्य से पहले अपवाद नहीं पकड़ सकते हैं, लेकिन मैं इन मामलों में भी वही करता हूं। –

+0

@Nils: दरअसल, वेक्टर कक्षा एक इटरेटर आधारित सीटीआर प्रदान करता है जिसे इस तरह की चीज़ के लिए सरणी के साथ जोड़ा जा सकता है। अधिक सुरक्षित, आईएमओ। – dirkgently

8

आप Boost's comma-separated list उपयोग कर सकते हैं। थोड़ा अक्षम शायद

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

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

, लेकिन यह आप के लिए अब कोई फर्क नहीं सकता है, और C++ 0x के साथ और ले जाने के लिए यह बहुत तेजी से हो जाएगा:

9

या सिर्फ एक समारोह बना सकते हैं और फोन है कि।

आप (के लिए सी ++ 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

वैश्विक स्थैतिक खराब है .... यदि आप कर सकते हैं तो उन्हें रद्द करें! अपवाद को पकड़ने का कोई तरीका नहीं है, वाल्ग्रिंड सोचता है कि यह एक रिसाव है, अगर आवेदन निकास पर कोई अपवाद है तो डीबग करना मुश्किल है! –

9

C++ 0x, मानक कंटेनरों के लिए प्रारंभकर्ता सूचियों की अनुमति होगी सिर्फ समुच्चय की तरह:

+०१२३५१६४१०६१
std::vector<int> bottles_of_beer_on_the_wall = {100, 99, 98, 97}; 

स्पष्ट रूप से अभी तक मानक नहीं है, लेकिन कथित रूप से यह GCC 4.4 से समर्थित है। मुझे एमएसवीसी में इसके लिए प्रलेखन नहीं मिल रहा है, लेकिन हर्ब सटर कह रहे हैं कि उनका सी ++ 0 एक्स समर्थन समिति से आगे है ...

3

वैश्विक का उपयोग करने के बजाय, मैं सुझाव दूंगा कि इसका उपयोग करना बेहतर होगा स्थानीय स्थैतिक मुख्य रूप से प्रवेश किए जाने से पहले आपके वेक्टर की शुरूआत होती है, वहां किसी भी अपवाद को मुख्य रूप से पकड़ा नहीं जाएगा। उदाहरण के लिए मान लीजिए कि आप एक प्रकार है जो जब यह एक अपवाद फेंक कर सकते हैं का निर्माण रहा है:

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