2012-03-08 7 views
18

मैं जानता हूँ कि मैं C++ ऐसा कर सकते हैं:C++ स्ट्रिंग सरणी प्रारंभ

string s[] = {"hi", "there"}; 

लेकिन वहाँ वैसे भी string s[] delcaring बिना एक सरणी इस तरह delcare के लिए है?

उदा।

void foo(string[] strArray){ 
    // some code 
} 

string s[] = {"hi", "there"}; // Works 
foo(s); // Works 

foo(new string[]{"hi", "there"}); // Doesn't work 
+3

गतिशील रूप से आवंटित सी-स्टाइल सरणी का उपयोग क्यों करेंगे? मैं सुझाव दूंगा कि आप इसके बजाय 'std :: vector' का उपयोग करें। सी ++ 11 का उपयोग करते समय आप प्रारंभिक सूचियों का उपयोग करके उन्हें बना सकते हैं, उदा। 'शून्य फू (वेक्टर ); foo ({"hi", "there"}); 'सी ++ 11 – Grizzly

उत्तर

18

सी ++ में आप कर सकते हैं। पहले से एक नोट: new सरणी नहीं है, इसके लिए कोई आवश्यकता नहीं है।

पहला, string[] strArray एक वाक्यविन्यास त्रुटि है, जो या तो string* strArray या string strArray[] होना चाहिए। और मुझे लगता है कि यह सिर्फ उदाहरण के लिए है कि आप किसी भी आकार पैरामीटर को पास नहीं करते हैं।

#include <string> 

void foo(std::string* strArray, unsigned size){ 
    // do stuff... 
} 

template<class T> 
using alias = T; 

int main(){ 
    foo(alias<std::string[]>{"hi", "there"}, 2); 
} 

ध्यान दें कि यह बेहतर होगा यदि आप एक अतिरिक्त पैरामीटर के रूप में सरणी आकार उत्तीर्ण करने की आवश्यकता नहीं किया था, और शुक्र है वहाँ एक तरीका है: टेम्पलेट्स!

template<unsigned N> 
void foo(int const (&arr)[N]){ 
    // ... 
} 

ध्यान दें कि यह केवल int x[5] = ... जैसे स्टैक सरणी से मेल खाएगा। या अस्थायी वाले, ऊपर alias के उपयोग से बनाए गए।

int main(){ 
    foo(alias<int[]>{1, 2, 3}); 
} 
8

सी ++ 11 से पहले, आप प्रकार [] का उपयोग करके सरणी शुरू नहीं कर सकते हैं। हालांकि नवीनतम C++ 11, (जोड़ता) initialisation प्रदान करता है ताकि आप इस तरह से यह कर सकते हैं:

string* pStr = new string[3] { "hi", "there"}; 

http://www2.research.att.com/~bs/C++0xFAQ.html#uniform-init

4
सी ++ 11 प्रारंभकर्ता यह बहुत आसान है सूचीबद्ध करता है के लिए समर्थन के साथ

देखें:

#include <iostream> 
#include <vector> 
#include <string> 
using namespace std; 

using Strings = vector<string>; 

void foo(Strings const& strings) 
{ 
    for(string const& s : strings) { cout << s << endl; } 
} 

auto main() -> int 
{ 
    foo(Strings{ "hi", "there" }); 
} 

अभाव है कि (विजुअल C++ 10.0 के लिए जैसे) आप इस तरह कर सकते हैं:

#include <iostream> 
#include <vector> 
#include <string> 
using namespace std; 

typedef vector<string> Strings; 

void foo(Strings const& strings) 
{ 
    for(auto it = begin(strings); it != end(strings); ++it) 
    { 
     cout << *it << endl; 
    } 
} 

template< class Elem > 
vector<Elem>& r(vector<Elem>&& o) { return o; } 

template< class Elem, class Arg > 
vector<Elem>& operator<<(vector<Elem>& v, Arg const& a) 
{ 
    v.push_back(a); 
    return v; 
} 

int main() 
{ 
    foo(r(Strings()) << "hi" << "there"); 
} 
+1

में काम करना चाहिए बहुत अधिक वर्बोज़: एक श्रेणी-आधारित लूप का उपयोग करें:' (ऑटो एस: स्ट्रिंग्स) cout << s << endl; ' – rwst

+0

@rwst: हाँ, आज यह है। धन्यवाद। मैं * संभवतः 2012 में सामान्य विज़ुअल सी ++ का समर्थन करने के लिए इटरेटर का उपयोग करता हूं। आपके द्वारा दिखाए जाने वाले साधारण लूप में थोड़ी अक्षमता होती है जिसमें यह तारों की प्रतिलिपि बनाता है लेकिन (1) यह लूप बॉडी में आईओ की तुलना में महत्वहीन है और (2) यह वैसे भी अप्रासंगिक है, चूंकि यह उदाहरण इस बारे में नहीं है, और (3) दक्षता के लिए पुनः लिखना (खराब मुहावरे को पढ़ाना) समझना मुश्किल नहीं है। तो, 2015 तक मुझे उपयोग किए गए इटरेटर लूप को रखने का कोई कारण नहीं दिखता है। ठीक करने के लिए स्वतंत्र महसूस करें। :) –

+0

@rwst: ठीक है मैंने इसे स्वयं अपडेट किया है। यह भी जांच की गई कि विजुअल सी ++ 10 उदाहरण वास्तव में वीसी 10 के साथ संकलित है। जब मैंने इसे देखा तो मुझे याद नहीं आया कि वीसी 10 समर्थित रावल संदर्भ, लेकिन, यह किया गया (कम से कम कोड संकलित करता है और सही परिणाम उत्पन्न करता है)। –