C++17 - std::any

Yeni gelen standartlarla C++ daha güvenli bir dil olmaya devam ediyor diye bahsetmiştik. Şimdi ise generic pointer olan void * ‘ a alternatif olarak sunulan
bir başka wrapper sınıf olan std::any’den bahsedelim.

Bu arada typesafe derken ne demek istediğimi aşağıdaki bir örnekle açıklayayım;

printf("onion price %s try\n", 5.2);

yukarıdaki kod parçasında aslında format bizden string türünden (char * veya const char *) beklerken programcı tarafından double veya float türünden bir değer parametre olarak geçilmiş. Derleme zamanında böyle bir kontrol olmadığından çalışma zamanında program büyük bir ihtimalle segmentation fault verecek. std::any’ de ise tür verisi de muhafaza edildiğinden derleme zamanında bu tarz hataları vererek daha güvenli programlar yazmaya yardımcı oluyor.

std::any a(5);

std::cout << std::any_cast<int>(a) << std::endl;

a = "cppturkey";

if (a.type() == typeid(const char *))
std::cout << std::any_cast<const char *>(a) << std::endl;

a.reset();

if (!a.has_value())
std::cout << "any doesnt have anything" << std::endl;

reset() fonksiyonu ile mevcut veri destruct edilerek std::any objesi boş hale gelir. Dikkat edilmesi gereken diğer bir husus ise std::any_cast eğer istenilen türe dönüştürülemezse exception fırlatır. Yine std::optional, std::variantda olduğu gibi obje hayata getirilirken std::in_place_type kullanılarak inşaa edilebilir. Yine benzer şekilde std::make_any factory fonksiyonu da kullanılabilir.

auto a = std::make_any<MyString>{"hello"};

std::any hangi türün kullanılacağını veya atanacağını bilmediği için ekstra bir memory kullanır. Bununla birlikte performans kazanımı için SBO(Small Buffer Optimization) yöntemini kullanır, bu yüzden sizeof(std::any) tutulan türden daha fazladır ve derleyicilerin SBO implementasyonuna bağlıdır.