微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何就地构造一个可选的聚合?

如何解决如何就地构造一个可选的聚合?

如何就地构造一个可选的聚合?看来我只能构造一个可选的单一事物,而不能构造一个可选的事物集合。

#include <optional>
#include <iostream>

struct Unmovable
{
    Unmovable(const Unmovable&) = delete;
    Unmovable(Unmovable&&) = delete;
    Unmovable& operator=(const Unmovable&) = delete;
    Unmovable& operator=(Unmovable&&) = delete;

    explicit Unmovable(const char* msg) {
        std::cout << msg << '\n';
    }
};

struct Things
{
    Unmovable one;
    Unmovable two;
};

int main(int argc,char* argv[]) {
    const bool y = argc > 1 && argv[1][0] == 'y';

    std::optional<Unmovable> optionalThing = y
        ? std::optional<Unmovable>{"works"}
        : std::nullopt;
    
    std::optional<Things> optionalThings = y
        ? std::optional<Things>{
#if ATTEMPT == 1
            "jadda","neida"
#elif ATTEMPT == 2
            {"jadda","neida"}
#elif ATTEMPT == 3
            Things{"jadda","neida"}
#elif ATTEMPT == 4
            Unmovable{"jadda"},Unmovable{"neida"}
#elif ATTEMPT == 5
            {Unmovable{"jadda"},Unmovable{"neida"}}
#elif ATTEMPT == 6
            Things{Unmovable{"jadda"},Unmovable{"neida"}}
#elif ATTEMPT == 7
            std::in_place_t{},"jadda","neida"
#elif ATTEMPT == 8
            std::in_place_t{},{"jadda","neida"}
#elif ATTEMPT == 9
            std::in_place_t{},Things{"jadda","neida"}
#elif ATTEMPT == 10
            std::in_place_t{},Unmovable{"jadda"},Unmovable{"neida"}
#elif ATTEMPT == 11
            std::in_place_t{},{Unmovable{"jadda"},Unmovable{"neida"}}
#elif ATTEMPT == 12
            std::in_place_t{},Things{Unmovable{"jadda"},Unmovable{"neida"}}
#endif
        } : std::nullopt;
}

解决方法

如果你可以使用C++20,那么你想要的是

std::optional<Things>{std::in_place,"jadda","neida"};

如本 live example 所示。您需要 C++20 的原因是 std::in_place_t 构造函数使用了

T(std::forward<Args>(args)...)

初始化对象,但 () 仅适用于具有构造函数的类,而 Things 没有。 C++ 已更新以解决此问题,而该更改使其成为 C++20。

在 C++17 中,您可以通过为 Things 提供初始化成员的构造函数来使此代码工作。那看起来像

struct Things
{
    Things(const char* msg1,const char* msg2) : one(msg1),two(msg2) {}
    Unmovable one;
    Unmovable two;
};

int main()
{
    std::optional<Things>{std::in_place,"neida"};
}

你可以看到在这个live example


如果您好奇,可以在 [dcl.init.general]/15.6.2.2

中找到在 C++20 中添加的用于处理此问题的新语言

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。