【发布时间】:2021-07-21 18:31:26
【问题描述】:
如何就地构造可选聚合?看来我只能构造一个可选的单一事物,而不是可选的事物聚合。
#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;
}
【问题讨论】:
-
标准库类型通常使用
()来初始化成员,因此不支持聚合初始化。这里特别是:eel.is/c++draft/optional#ctor-13 -
因此,您可以通过为 Things 提供构造函数或使用转发到
{}-style init: compiler-explorer.com/z/P431GjaEv 的包装器类型来解决此问题。 -
查看
emplace()的文档。 -
Things(char const* msg1, char const* msg2) : one{msg1}, two{msg2} {}和std::make_optional<Things>("jadda", "neida")。 -
@SamVarshavchik emplace 无法工作,原因与
std::in_place_t构造函数重载不起作用的原因相同。
标签: c++ c++17 aggregate-initialization construction stdoptional