从另一个 std::optional 和其他东西初始化 std::optional 的惯用方法
Idiomatic way to initialise std::optional from another std::optional and something else
我想从另一个 std::optional
和一些附加参数初始化一个 std::optional
,前提是后者 std::optional
不为空。不幸的是 std::optional::optional
4) 和 5) 不合适,因为参数的数量不同。
我想出了以下内容,但仍然感觉过多。我特别不喜欢明确地为 lambda 指定 return 类型。
是否有更好的(更简洁和更具表现力的)方法来实现这一点?
#include <iostream>
#include <optional>
#include <tuple>
struct A {
A(std::optional<int> oi, float f, char c)
:
val{
[&] () -> decltype(val) /* I don't like specifying type here */ {
if (oi)
return {{*oi, f, c}};
else
return std::nullopt;
}()
}
{
}
std::optional<std::tuple<int, float, char>> val;
};
int main()
{
auto print = [](auto& r) {
if (r)
std::cout
<< std::get<0>(*r) << "; "
<< std::get<1>(*r) << "; "
<< std::get<2>(*r) << std::endl;
else
std::cout << "nullopt" << std::endl;
};
auto one = A({}, 1.0, 'c');
print(one.val);
auto two = A(10, 2.0, 'c');
print(two.val);
}
相信编译器会做正确的事情:
A(std::optional<int> oi, float f, char c) {
if (oi) {
val.emplace(*oi, f, c);
}
}
这当然也是 map()
成员函数的一个很好的用例†,您可以将其编写为非成员函数:
A(std::optional<int> oi, float f, char c)
: val(map(oi, [&](int i){ return std::tuple(i, f, c); }))
{ }
†TartanLlama 最近在 P0798 中提出。
我想从另一个 std::optional
和一些附加参数初始化一个 std::optional
,前提是后者 std::optional
不为空。不幸的是 std::optional::optional
4) 和 5) 不合适,因为参数的数量不同。
我想出了以下内容,但仍然感觉过多。我特别不喜欢明确地为 lambda 指定 return 类型。
是否有更好的(更简洁和更具表现力的)方法来实现这一点?
#include <iostream>
#include <optional>
#include <tuple>
struct A {
A(std::optional<int> oi, float f, char c)
:
val{
[&] () -> decltype(val) /* I don't like specifying type here */ {
if (oi)
return {{*oi, f, c}};
else
return std::nullopt;
}()
}
{
}
std::optional<std::tuple<int, float, char>> val;
};
int main()
{
auto print = [](auto& r) {
if (r)
std::cout
<< std::get<0>(*r) << "; "
<< std::get<1>(*r) << "; "
<< std::get<2>(*r) << std::endl;
else
std::cout << "nullopt" << std::endl;
};
auto one = A({}, 1.0, 'c');
print(one.val);
auto two = A(10, 2.0, 'c');
print(two.val);
}
相信编译器会做正确的事情:
A(std::optional<int> oi, float f, char c) {
if (oi) {
val.emplace(*oi, f, c);
}
}
这当然也是 map()
成员函数的一个很好的用例†,您可以将其编写为非成员函数:
A(std::optional<int> oi, float f, char c)
: val(map(oi, [&](int i){ return std::tuple(i, f, c); }))
{ }
†TartanLlama 最近在 P0798 中提出。