Вариативные типы
Тип optional<T> представляет собой объединение типов T и void, т.е. значение может отсутствовать. Может быть использован при работе с базами данных (аналог NULL) или для уменьшения количества исключений. Пусть функция intersect должна вернуть координаты точки пересечения двух отрезков. Можно написать функцию так:
Point intersect(Segment s1, Segment s2) {
if(/*есть пересечение*/) { ... return {x,y};}
else throw nointersect();
}
...
try {
auto p=intersect(s1,s2);
//
}
catch(nointersect&) {
//
}
Формально функция написана правильно и возращает либо Point, либо nointersect, но обработка результата вызова нарушает логику программы. При использовании optional логика программы записывается более привычно через if:
optional<Point> intersect(Segment s1, Segment s2) {
if(/*есть пересечение*/) { ... return Point{x,y};}
else return {}; //
}
...
if(auto p=intersect(s1,s2))
//
}
else {
//
}
Метод value_or возвращает значение или аргумент метода, если значение отсутствует.
Вместо небезопасного union в C++ предлагается тип variant<T1,T2,...>.
variant<int,double,string> v(1);
if(holds_alternative<int>(v)) {
int i=get<int>(v);
}
try {
double d=get<double>(v); //
}
catch (bad_variant_access&) {}
Тип any позволяет хранить значение любого типа.
any a = 1;
int i=any_cast<int>(a); //
try {
auto s=any_cast<double>(a); //
}
catch(bad_any_cast&) { }
if(a.type()==typeid(int)) {
auto &r=any_cast<int&>(a); //
++r;
}
if(int *p=any_cast<int>(&a)) { //
++*p;
}