ein*_*ica 2 c++ idioms syntactic-sugar c++17 std-variant
这是受到我给新手用户的回答的启发,我建议他们使用 anstd::variant而不是 union。
通过工会,您可能会遇到如下情况:
struct Box {
    struct Item { float value; };
    using Boxes = std::vector<Box>;
    union Value {
        Item item;
        Boxes boxes;
    };
    Value contents;
    std::string label;
};
Run Code Online (Sandbox Code Playgroud)
(不完全是最初的问题,我在这里接受了一些诗意的许可。)并且使用一个变体,该类可能如下所示:
struct Box {
    struct Item { float value; };
    using Boxes = std::vector<Box>;
    std::variant<Item, Boxes> contents;
    std::string label;
};
Run Code Online (Sandbox Code Playgroud)
问题是,使用第一个变体,我可以写
if (box.contents.boxes.size() > 2) { foo(); }
Run Code Online (Sandbox Code Playgroud)
如果我已经确定会有子框,这就会起作用。
对于std::variant,我必须写:
if (std::get<Boxes>(box.contents).size() > 2) { foo(); }
Run Code Online (Sandbox Code Playgroud)
我觉得第二个版本的可读性要差得多,有点混乱,而且很分散注意力。另外 - 我必须知道 的类型boxes。
在我的代码中,我可以做些什么来让我的用户无需进行此类std::get()调用,并使他们的生活更加愉快?
只需添加一些访问器包装std::get:
struct Box {
    struct Item { float value; };
    using Boxes = std::vector<Box>;
    std::variant<Item, Boxes> contents;
    std::string label;
    decltype(auto) item()       { return std::get<Item>(contents); }
    decltype(auto) item() const { return std::get<Item>(contents); }
    decltype(auto) boxes()       { return std::get<Boxes>(contents); }
    decltype(auto) boxes() const { return std::get<Boxes>(contents); }
};
Run Code Online (Sandbox Code Playgroud)
然后是这样的:
if (box.boxes().size() > 2) { foo(); }
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           683 次  |  
        
|   最近记录:  |