Pertanyaan tubuh inisialisasi array sebagai parameter fungsi (C-array), mungkinkah?


Saya mencari bantuan dalam situasi berikut:
Saya memiliki beberapa kelas dan beberapa metode di dalamnya, sintaks seperti ini:

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

Jadi saya ingin menyebut metode ini seperti

SomeClass::doSomething({ 0, 1, 2, 3, 4 });

Apakah mungkin dalam bahasa apa pun? Implementasi Any (C ++, C, obj-c, obj-c ++) diterima! Saya tahu bahwa blok inisialisasi ini adalah badan array, seperti

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

Tetapi antarmuka akan terlihat bagus, saya pikir, jika tidak akan ada variabel temp sebelum fungsi panggilan (karena kita tidak perlu mengetahui jenis parameter di kelas-klien). Jadi, adakah kesempatan untuk membuat ini?


17
2017-10-05 07:17


asal


Jawaban:


Ini tentang C ++ 11 daftar penginisialisasi (bagian 18,9).

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

foo ({10, 20, 30});

Hanya compiler yang dapat membuat daftar penginisialisasi, tetapi Anda dapat memperlakukannya seperti kontainer STL-style standar dengan begin(), end(), size(), dan iterator akses acak.

std::vector (dan saya mengharapkan beberapa wadah lain) sekarang dapat dibangun dengan daftar penginisialisasi, jadi

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

setara dengan

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

kecuali bahwa itu mungkin melakukan alokasi lebih sedikit. Perhatikan bahwa const char* telah berubah menjadi std::string secara otomatis.


8
2017-10-05 07:19



Di C99 ini berfungsi:

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

..dan hal serupa bisa dilakukan dengan struct.


22
2017-10-05 07:33



Jika initializer_list tidak tersedia, dan array kebanyakan kecil, ada opsi lain, overloading << operator untuk std :: vector seperti ini:

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;
}

Dengan itu, Anda dapat melakukan ini:

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

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

Ada harga yang harus dibayar untuk kenyamanan inisialisasi baris tunggal dan tidak perlu menentukan ukuran vektor. Salinan vektor sebelumnya dibuat untuk setiap elemen yang ditambahkan, membuat waktu berjalan setidaknya kuadratik dalam ukuran vektor - itulah mengapa ini paling cocok untuk vektor dan kasus pendek ketika kinerja tidak penting. Ada solusi yang lebih baik untuk C ++ 11, seperti yang ditunjukkan dalam jawaban spraff.


2
2017-09-24 23:12