c++ - 如何就地构建可选聚合?

标签 c++ c++17 aggregate-initialization construction stdoptional

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

#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, "jadda", "neida"};
}
你可以看到在这个 live example 中工作

如果您好奇,可以在 [dcl.init.general]/15.6.2.2 中找到在 C++20 中添加的用于处理此问题的新语言。

关于c++ - 如何就地构建可选聚合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67299584/

相关文章:

c++ - 与主函数不同的文件中的自定义 QWidget

C++自动推导模板成员指针的类型

c++ - C++0x 中的缩小转换。只是我,还是这听起来像是一个重大变化?

c++ - 如何找出DC的尺寸?

c++ - 使用指针 C++ 进行转换

c++ - 错误 : Control reaches end of non-void function in C++ for selection sort function

c++ - 在自己的成员函数中构造类时如何强制类模板参数推导?

c++ - 这个来自 Effective Modern C++ 的项目仍然是最新的吗?

c++ - 聚合/指定的C++结构初始化:直接引用另一个字段

c++ - 初始化中的评估顺序