C Stili Dizilerden std::array'e...

Programlama dillerinde diziler uygulanırken syntax olarak genelde C stili dizilerden ilham aldılar. Özellik olarak C stili dizilerin üzerine ihtiyaca göre üye fonksiyonlar da eklendi.

C++11 ile gelen std::array ile C stili dizilerden çok daha fazla kullanışlılığa ve okunabilirliğe sahip kod yazılırken performans anlamında ise neredeyse aynı seviyede sayılır.

std::array C stili diziler gibi statik boyutludur ve bellekte derleme zamanında yer ayrılır.

std::array’ e genel bakış

std::array arka planda C stili dizinin ve ilgili üye fonksiyonlarının bulunduğu array sınıf şablonu yapısındadır.

1
2
3
4
5
6
7
8
9
template<typename T, size_t N>
class array
{
public:
T _data[N];
T& operator[](size_t);
const T& operator[](size_t) const;
// other member functions and typedefs
};

std::array kullanmak için #include <array> ile array kütüphanesi projeye eklenir. std::array uzunluğu derleme zamanında hesaplandığından ve o bilgi oluşturulan nesne içerisindeki bir değişkende saklandığından sonradan o std::array nesnesinin uzunluğunu öğrenmek kolay ve hızlıdır.

std::array oluşturmak

std::array iki bileşenden oluşur: İlki array içinde saklanacak elemanların tipi ve ikincisi array nesnesinin ne kadar eleman tutacağı (yani uzunluğu).

1
2
3
4
5
//a1 dizisi 10 int tipinde eleman tutar
std::array<int, 10> a1;

//Tanımlama sırasında değerler atanabilir
std::array<int, 5> a2 = {-1, 1, 3, 2, 0};

Ayrıca mevcut diziler yeni dizilere atama yoluyla kopyalanabilir.

1
2
3
4
5
//atama yoluyla yeni kopya dizi oluşturma
auto a3 = a2;

//constructor ile de kopya dizi oluşturulabilir
auto a4(a2);

Aynı uzunluktaki başka bir dolu diziye = operatörü ile atama yapılabilir ama uzunluklar aynı olmadığında hata alınacaktır.

1
2
3
4
5
6
//a3 dizisi değerlerini a2 dizisine atama
a2 = a3;

// '=' operatörü iki dizi aynı boyutta ise kullanılabilir.
//Hata:
//a1 = a2; //<[...],10> vs <[...],5>! geçersiz

std::array içindeki verilere erişmek

std::array içindeki verilere dizilerden alıştığımız şekilde [] operatörü ile de erişebiliriz ama sınır kontrolü yapmadığından dizi boyutundan farklı değerlerde hata alınacaktır.

1
2
//beklenilen şekilde değer atamaları gerçekleşir
a3[0] = -2;

Sınır kontrolü için at() üye fonksiyonu kullanılabilir.

1
2
3
4
std::cout << "a2.at(4): " << a2.at(4) << std::endl;

// Sınır kontrolü istisna yaratabilir. Deneyin:
//auto b = a2.at(10);

Ayrıca front() ve back() üye fonksiyonlarıyla array nesnesindeki ilk ve son değerlere erişebiliriz.

data() üye fonksiyonu

std::array dolaylı yoldan raw pointera dönüşmez. Pointer temelli kullanmak isteniyorsa data() üye fonksiyonu kullanmak gerekir.
Örneğin buffer arayüzü için C stili API yazalım:

1
2
3
4
void carr_func(int * arr, size_t size)
{
std::cout << "carr_func - arr: " << arr << std::endl;
}

carr_func fonksiyonunda ilk parametreye std::array gönderirsek derleyici hatası oluşur.

1
2
3
4
5
6
../../array.cpp:44:2: error: no matching function for call to 'carr_func'
carr_func(a2);
^~~~~~~~~
../../array.cpp:4:6: note: candidate function not viable: no known conversion
from 'std::array<int, 5>' to 'int *' for 1st argument
void carr_func(int * arr)

Bunun yerine data() üye fonksiyonunu kullanınca sorun çözülür.

1
2
3
4
5
//Error:
//carr_func(a2, a2.size());

//OK:
carr_func(a2.data(), a2.size());

size() ve empty() üye fonksiyonları

size() üye fonksiyonuyla dizinin uzunluğu öğrenilebilir. empty() üye fonksiyonu ise dizinin içeriği boş ise true, dolu ise false döndürür.

1
2
3
4
a2.size(); //5

std::array<int, 0> a_empty;
a_empty.empty(); //true

Container(kap) işlemleri

std::array container sınıfı olduğundan temel container arayüzlerini sunmaktadır. std::array statik uzunlukta olduğundan dinamik olarak uzunluk değiştirme gibi işlemler mevcut değildir. Ancak std::sort gibi sıralama fonksiyonları kullanılabilir.

1
std::sort(a1.begin(), a1.end());

İleri okuma ve kaynaklar

Cisco Router Yönlendirme

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×