O único requisito para o parâmetro de tipo do std::optional<T>
modelo de classe mencionado em [optional.optional.general] p3 é que o tipo T
seja Destructible .
Suponha que eu tenha uma classe muito restritiva que atenda a esse requisito:
class R
{
public:
~R() = default;
// This works thanks to guaranteed copy elision since C++17.
static R create()
{
return R();
}
void do_something()
{
}
private:
R() = default;
R(const R&) = delete;
R& operator=(const R&) = delete;
R(R&&) = delete;
R& operator=(R&&) = delete;
};
Mas essa classe ainda é perfeitamente utilizável:
void test_1()
{
R obj = R::create();
obj.do_something();
}
A questão é: eu realmente posso ter um objeto utilizável do tipostd::optional<R>
? Por "utilizável" eu quero dizer um objeto que contém valor. Se sim, então como eu construo esse valor ali?
O código a seguir obviamente falha porque cada construtor de R
é inacessível:
void test_2()
{
std::optional<R> o(R::create()); // Error: no matching constructor
}
Editar:
Não seria legal se std::optional
houvesse um construtor que aceitasse um construtor ?
template <typename Builder>
optional::optional(disabmiguating_tag, Builder f)
: my_internal_union(f())
{
}
com construtor apropriado, é my_internal_union
claro...