2011-10-05 28 views
17

sonraki durumda biraz yardım arıyorum:
bazı sınıf ve içinde bir metoda sahip, sözdizimi şu şekildedir:dizinin başlatma birimi işlev parametresi olarak (C-dizisi) mümkün mü?

class SomeClass { 
    public: 
      void doSomething(int *a); 
}; 

yüzden

SomeClass::doSomething({ 0, 1, 2, 3, 4 }); 
gibi bu yöntemi çağırmak istiyorum

Herhangi bir dilde mümkün müdür? Herhangi bir (C++, C, obj-c, obj-C++) uygulaması açığız! Bu başlatma bloğu harika görünecek

int *a = { 0, 1, 2, 3, 4 }; 
SomeClass::doSomething(a); 

Ama arayüzü gibi, dizinin bir vücut olduğunu biliyoruz, bence, bilmemiz gerekmez olarak (işlev çağrılmadan önce hiçbir geçici değişkenleri olacak eğer sınıf-istemcide parametre tipi. Yani bunu yapmak için bir şans var mı?

cevap

8

Bu, C++ 11 initializer lists (bölüm 18.9) ile ilgilidir.

void foo (std :: initializer_list <int> inputs) { 
    for (auto i : inputs) { 
     // ... 
    } 
} 

foo ({10, 20, 30}); 

Sadece derleyici bir başlatıcı listesi oluşturabilir, ancak begin(), end(), size() ve rasgele erişimli adım adım elde standart STL tarzı konteyner gibi davranabilirsiniz.

std::vector

(ve bazı diğer kaplar beklemek) şimdi

std :: vector <std :: string> foo {"a", "b"}; 

daha az sayıda tahsisleri gerçekleştirebilir dışında

std :: vector <std :: string> foo; 
foo .push_back ("a"); 
foo .push_back ("b"); 

eşdeğerdir, başlatıcı listeleri ile yapılabilir. const char*'un otomatik olarak std::string'a çevrildiğini unutmayın.

functionThatTakesIntPtrOrArray((int []){ 1, 2, 3, 4 }); 

..ve benzer şeyler yapılar ile yapılabilir:

+0

Aslında bu, C++ 11'in tekdüze başlatması sayesinde * herhangi bir * konteyner sınıfı ile çalışacaktır. –

20

C99 bu çalışır. initializer_list mevcut değildir ve diziler başka bir seçenek böyle << std için operatöre :: vektör aşırı vardır, çoğunlukla küçükse

+0

Çok teşekkürler, beni çok fazla sabreden kurtardı! –

+2

Ne yazık ki C++ 'da çalışmıyor. "Geçici dizinin adresini almak" hatasını alırsınız. – Timmmm

+0

Visual Studio 2017 (v141) üzerinde çalışmıyor – sergiol

2

: aldığımızda

template <typename T> 
inline std::vector<T> operator <<(const std::vector<T>& vec, const T& val) { 
    std::vector<T> result(vec); 
    result.push_back(val); 
    return result; 
} 

, bunu yapabilirsiniz:

void foo (const std::vector<int>& inputs) { 
    // ... 
} 

foo (std::vector<int>() << 10 << 20 << 30); 

Tek satırlık başlatma ve vektör boyutunu belirtmek zorunda kalmadan bu kolaylık için ödeme yapılması gereken bir ücret vardır. Önceki vektörün bir kopyası, eklenen her eleman için yaratılır, bu da vektör boyutunda en azından ikinci dereceden çalışma süresi sağlar - bu yüzden performansın önemli olmadığı durumlarda kısa vektörler ve durumlar için en uygun olanı budur. Spraff'ın cevabında belirtildiği gibi C++ 11 için daha iyi bir çözüm var.

İlgili konular