рдХреНрдпрд╛ рдЧрд▓рдд рд╣реИ std :: рдЖрдзреБрдирд┐рдХ C ++ рдореЗрдВ рдЬрд╛рдПрдБ

рд╕рд┐рдЧреНрдорд╛ рдЯрд╛рдЗрдк рдФрд░ рдЖрдк


рдЖрдЗрдП рдПрдХ рд╕рд░рд▓ рд▓реЗрдХрд┐рди рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ - рд╕рд┐рдЧреНрдорд╛ рдкреНрд░рдХрд╛рд░ред

рдПрдХ рд╕рд┐рдЧреНрдорд╛ рдкреНрд░рдХрд╛рд░ (рдЯрд╛рдЗрдк-рд╕рдо, рд▓реЗрдмрд▓ рдпреВрдирд┐рдпрди) рдореЗрдВ рдПрдХ рдФрд░ рдХрдИ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рд╕реЗ рдХреЗрд╡рд▓ рдПрдХ рдХрд╛ рдорд╛рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, INI рдЬреИрд╕реА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдЯрд┐рдВрдЧ рдХреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ, рдкреВрд░реНрдгрд╛рдВрдХ рдпрд╛ рдмреВрд▓рд┐рдпрди рдорд╛рди рд╣реЛрдиреЗ рджреЗрдВред рдЕрдЧрд░ рд╣рдо C ++ рдореЗрдВ рдЕрдкрдиреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦреЗрдВрдЧреЗ:

struct Setting {
    union {
        string str;
        int num;
        bool b;
    };
    enum Type { Str, Int, Bool };
    Type tag;
};

//     
using Settings = unordered_map<string, Setting>;

, :

  • tag .
  • .
  • . string, .

, , . getType(), asBool(), asString(), . , , . .

, - . C++17 ! std::variant, .

std::variant


variant тАФ , , . variant<string, int, bool>. variant :

variant<string, int, bool> mySetting = string("Hello!"); // 
mySetting = 42; // 
mySetting = false;

variant, , , . . , :

match (theSetting) {
    Setting::Str(s) =>
        println!("A string: {}", s),
    Setting::Int(n) =>
        println!("An integer: {}", n),
    Setting::Bool(b) =>
        println!("A boolean: {}", b),
};

C++17(*). std::visit. variant, , -, variant.

-? тАФ , :

struct SettingVisitor {
    void operator()(const string& s) const {
        printf("A string: %s\n", s.c_str());
    }

    void operator()(const int n) const {
        printf("An integer: %d\n", n);
    }

    void operator()(const bool b) const {
        printf("A boolean: %d\n", b);
    }
};

, , - . тАж . -?

make_visitor(
    [&](const string& s) {
        printf("string: %s\n", s.c_str());
        // ...
    },
    [&](const int d) {
        printf("integer: %d\n", d);
        // ...
    },
    [&](const bool b) {
        printf("bool: %d\n", b);
        // ...
    }
)

, make_visitor, . .

template <class... Fs>
struct overload;

template <class F0, class... Frest>
struct overload<F0, Frest...> : F0, overload<Frest...>
{
    overload(F0 f0, Frest... rest) : F0(f0), overload<Frest...>(rest...) {}

    using F0::operator();
    using overload<Frest...>::operator();
};

template <class F0>
struct overload<F0> : F0
{
    overload(F0 f0) : F0(f0) {}

    using F0::operator();
};

template <class... Fs>
auto make_visitor(Fs... fs)
{
    return overload<Fs...>(fs...);
}

, C++11. , F0, , .

, ! C++17 ,

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

, ? , (if constexpr) C++17:

[](auto& arg) {
    using T = std::decay_t<decltype(arg)>;

    if constexpr (std::is_same_v<T, string>) {
        printf("string: %s\n", arg.c_str());
        // ...
    }
    else if constexpr (std::is_same_v<T, int>) {
        printf("integer: %d\n", arg);
        // ...
    }
    else if constexpr (std::is_same_v<T, bool>) {
        printf("bool: %d\n", arg);
        // ...
    }
}

?


std::visit тАФ . : -. , :

  1. , ,
  2. , :
    • ,
    • using- , C++17.


  3. , constexpr if, type_traits, std::decay.

C++-, ┬л┬╗ . - , .

?


ISO C++, . , , . , - , . , тАФ - . , тАж ? ? variant , ? , C++17 , - make_visitor. .

? , . , , SFINAE, - :

template <typename F>
typename std::enable_if<!std::is_reference<F>::value, int>::type
foo(F f)
{
    // ...
}

, std::visit. , , , int string .

, C++ , , . , Effective C++ Effective Modern C++, . , , . , . .

?


, C++ , (*). , . , C++, , C. .

, . D, , . Rust, , unique_ptr shared_ptr ( ), . 2017 , #include.

, , , , , . , . C++ , .

, variant, . - тАФ , . , ┬л , ++┬╗.


1. "$\Sigma$-" , . A B, - A B. ┬л┬╗ -: -, , .. , A B A B.

2. P0095R1 C++.

3.

Source: https://habr.com/ru/post/hi415737/


All Articles