std::array dan std::vector sudah menjadi sahabat kita sejak Section Array dan String: yang pertama membungkus array C-style dengan ukuran tetap, yang kedua adalah array dinamis yang tumbuh sendiri. Kali ini kita tidak mengulang cara mendeklarasikannya, melainkan menelusuri operasi lanjutan yang membuat keduanya betul-betul berguna — fill, swap, insert, erase, serta pasangan push_back/emplace_back yang sering dipertukarkan tanpa sadar. Memahami mekanisme di balik operasi-operasi ini memudahkan kita menebak biayanya dan memilih container yang tepat.

Sketsa Ulang: Dua Karakter yang Berbeda #

Karakter dasarnya bisa dirangkum dalam satu tabel supaya seluruh pembahasan di bawah punya pijakan.

Aspekstd::arraystd::vector
Ukurantetap saat kompilasidinamis saat runtime
Penyimpanandi dalam objek (stack)buffer di heap
Menambah elementidak bisapush_back, emplace_back, insert
Ukuran tipesizeof mencakup semua elemensizeof tetap kecil, data di luar
Cocok untukdata yang jumlahnya pastidata yang jumlahnya berubah

Aturan praktisnya sederhana: bila jumlah elemen pasti dan tidak berubah — misalnya tiga sumbu koordinat — std::array memberi tipe yang paling ringan. Begitu ada pertanyaan “berapa banyak, tergantung input”, jawabannya std::vector.

Operasi yang Sering Dipakai #

Program berikut memperagakan fill pada array, lalu siklus hidup lengkap sebuah vector: menambah, menyisipkan, menghapus, dan menukar isi.

cpp
#include <array>     // std::array: container ukuran tetap
#include <iostream>  // std::cout
#include <string>    // std::string
#include <vector>    // std::vector: container dinamis

// struct kecil agar push_back vs emplace_back bisa dibedakan
struct Produk {
    std::string nama;
    int harga;
};

void cetak(const std::vector<std::string>& v, const std::string& label) {
    std::cout << label << ":";
    for (const std::string& s : v) std::cout << ' ' << s;
    std::cout << "\n";
}

int main() {
    // --- std::array: ukuran tetap, dikenal saat kompilasi ---
    std::array<int, 5> sensor;
    sensor.fill(0);            // isi seluruh elemen dengan nilai sama
    sensor[3] = 42;            // akses langsung seperti array biasa
    std::cout << "array fill :";
    for (int x : sensor) std::cout << ' ' << x;
    std::cout << "\n";

    // --- std::vector: ukuran tumbuh sesuai kebutuhan ---
    std::vector<std::string> keranjang;
    keranjang.push_back("Apel");      // menerima string: dibangun lalu dipindah masuk
    keranjang.emplace_back("Jeruk");  // bangun string langsung di dalam vector
    keranjang.insert(keranjang.begin() + 1, "Mangga");
    cetak(keranjang, "keranjang  ");

    keranjang.erase(keranjang.begin() + 2);  // hapus elemen ketiga ("Jeruk")
    cetak(keranjang, "setelah erase");

    std::cout << "size: " << keranjang.size()
              << ", front: " << keranjang.front()
              << ", back: " << keranjang.back() << "\n";

    // --- push_back vs emplace_back pada struct ---
    std::vector<Produk> toko;
    toko.push_back({"Kopi", 15000});     // buat Produk sementara, lalu pindahkan
    toko.emplace_back("Teh", 8000);      // bangun Produk langsung di slot akhir
    std::cout << "toko: " << toko[0].nama << " " << toko[0].harga
              << ", " << toko[1].nama << " " << toko[1].harga << "\n";

    // --- swap: tukar isi dua vector dalam satu langkah ---
    std::vector<int> a = {1, 2, 3};
    std::vector<int> b = {9, 8, 7, 6};
    a.swap(b);
    std::cout << "a berisi:";
    for (int x : a) std::cout << ' ' << x;
    std::cout << "\n";
    std::cout << "b berisi:";
    for (int x : b) std::cout << ' ' << x;
    std::cout << "\n";

    return 0;
}

Output yang Dihasilkan:

text
array fill : 0 0 0 42 0
keranjang  : Apel Mangga Jeruk
setelah erase: Apel Mangga
size: 2, front: Apel, back: Mangga
toko: Kopi 15000, Teh 8000
a berisi: 9 8 7 6
b berisi: 1 2 3

Mari kita bedah:

  1. Baris 20-21 (sensor.fill(0)): fill mengisi seluruh elemen array dengan satu nilai — cara aman “menolkan” buffer sebelum dipakai, tanpa loop manual.
  2. Baris 29-31 (menambah elemen): push_back menaruh nilai di ujung; insert menyisipkan di posisi iterator tertentu, sehingga "Mangga" muncul sebagai elemen kedua. Menyisipkan di tengah menggeser semua elemen setelahnya — biaya yang tumbuh seiring panjang vector.
  3. Baris 34 (erase): menghapus elemen ketiga; elemen-elemen setelahnya digeser maju satu slot dan size berkurang. Perhatikan erase menerima iterator, bukan indeks.
  4. Baris 37-39: setelah semua operasi, tersisa Apel Mangga; front() dan back() memberi elemen paling depan dan paling belakang tanpa kita menghitung indeks.
  5. Baris 43-44 (dua gaya menambah Produk): keduanya menghasilkan vector yang sama, tetapi jalurnya berbeda — ini yang kita bedah di bagian berikutnya.
  6. Baris 51 (a.swap(b)): isi kedua vector tertukar total. Yang ditukar hanyalah tiga penunjuk internal (buffer, ukuran, kapasitas), bukan elemen satu per satu, sehingga biayanya konstan berapa pun panjangnya.

push_back vs emplace_back #

Perbedaan keduanya ada pada di mana objek dibangun. toko.push_back({"Kopi", 15000}) membangun objek Produk sementara di luar vector, lalu memindahkan objek itu ke slot penyimpanan di ujung vector. Sementara itu toko.emplace_back("Teh", 8000) meneruskan argumen langsung ke constructor Produk yang bekerja di slot akhir vector — tidak ada objek sementara sama sekali. Untuk struct sederhana seperti Produk, selisihnya nyaris tak terukur; untuk tipe yang konstruksinya mahal (misalnya std::string panjang), emplace_back menghemat satu langkah pindah.

Kapan array, Kapan vector #

Kita sekarang punya keputusan yang cukup untuk sebagian besar kasus. Pilih std::array bila ukuran adalah bagian dari tipe datanya: koordinat 3D, matriks kecil, buffer tetap — keuntungannya tidak ada alokasi heap dan compiler tahu ukurannya saat kompilasi. Pilih std::vector untuk semua koleksi lain: hasil parsing file, daftar produk yang bertambah, buffer yang ukurannya dihitung saat runtime. Operasi di tengah (insert, erase) tetap tergolong mahal pada keduanya; bila program kita sangat sering menyisip dan menghapus di tengah atau di kedua ujung, Chapter berikutnya menyiapkan kandidat yang lebih cocok: std::deque dan std::list.

Rujukan resmi: cppreference — std::array , cppreference — std::vector , cppreference — vector::emplace_back .