Giriş
Şu satırı dahil ederiz.
Örnek
Şöyle yaparız.
Tipe göre farklı iş yapmak için şöyle yaparız.
Elimizde variant dönen bir metod olsun.
if kullanmak için şöyle yaparız.
Variant değişirse derleme zamanı kontrol eklemek için şöyle yaparız.
Açıklaması şöyle
Eğer farklı tipler döneceksek şöyle yaparız.
Şu satırı dahil ederiz.
#include <variant>
Birinc parametre overloaded metodu, ikinci parametre ise variant nesnesidir.Örnek
Şöyle yaparız.
bool input = ...;
std::variant<int, long, double, std::string> myVariant;
if(input)
myVariant = "Example1";
else
myVariant = 3.14;
std::visit([](auto&& arg) { std::cout << arg << std::endl; }, myVariant);
ÖrnekTipe göre farklı iş yapmak için şöyle yaparız.
std::variant<int, long, double, std::string> v = ...;
std::visit(overloaded {
[](auto arg) { std::cout << arg << ' '; },
[](double arg) { std::cout << std::fixed << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
}, v);
ÖrnekElimizde variant dönen bir metod olsun.
#include <variant>
#include <string>
struct CellNotFound {};
struct Cell {};
using CellFindResult = std::variant<CellNotFound, Cell>;
CellFindResult Find(std::string segment) {
CellFindResult result { CellNotFound {} };
// Search code here.
return result;
}
Metodun sonucuna göre farklı iş yapmak için şöyle yaparız.template<class... Ts>
struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
void cellsAndStuff()
{
std::visit(overloaded
{
[&](CellNotFound)
{
// the not-found code
},
[&](Cell c)
{
// code on cell found
}
}, Find("foo"));
}
Örnekif kullanmak için şöyle yaparız.
template <typename T, typename... Args>
struct is_one_of:
std::disjunction<std::is_same<std::decay_t<T>, Args>...> {};
std::visit([](auto&& arg) {
static_assert(is_one_of<decltype(arg),
int, long, double, std::string>{}, "Non matching type.");
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, int>)
std::cout << "int with value " << arg << '\n';
else if constexpr (std::is_same_v<T, double>)
std::cout << "double with value " << arg << '\n';
else
std::cout << "default with value " << arg << '\n';
}, v);
ÖrnekVariant değişirse derleme zamanı kontrol eklemek için şöyle yaparız.
template <typename... Args>
struct visit_only_for {
// delete templated call operator
template <typename T>
std::enable_if_t<!is_one_of<T, Args...>{}> operator()(T&&) const = delete;
};
// then
std::visit(overloaded {
visit_only_for<int, long, double, std::string>{}, // here
[](auto arg) { std::cout << arg << ' '; },
[](double arg) { std::cout << std::fixed << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
}, v);
std::visit ve Return Type
Açıklaması şöyle
"The value returned by the selected invocation of the visitor, converted to the common type of all possible std::invoke expressions"Yani visitor benzer tipler dönmeli. Klasik bir visitor'da şöyle yaparız.
struct Visitor {
using some_type = /*...*/;
some_type operator()(A const& a);
some_type operator()(B const& b);
};
ÖrnekEğer farklı tipler döneceksek şöyle yaparız.
template <typename Visitor, typename ... Ts>
decltype(auto) my_visit(Visitor&& vis, const std::variant<Ts...>& var)
{
return std::visit([&](auto&& e)
-> std::common_type_t<decltype(vis(std::declval<Ts>()))...>
{
return vis(e);
}, var);
}
Yeni bir variant dönebiliriz.Şöyle yaparızstruct Functor {
std::variant<A,B> operator()(A const& a) const {
return A{2*a.i};
}
std::variant<A,B> operator()(B const& b) const {
return B{3*b.j};
}
};
Hiç yorum yok:
Yorum Gönder