Według standardu (przynajmniej tyle zrozumiałem) std::optional<T>
zainicjalizowany przy użyciu std::nullopt
powinien nie tworzyć obiektu typu T, a z moich obserwacji wynika, że GCC, Clang i MSVC robią to nawet gdy T ma usunięty domyślny konstruktor.
struct TestStruct {
int a;
int test() { return std::rand() % 1000; }
virtual void vir() {}
virtual ~TestStruct() {}
private:
TestStruct() = delete;
};
int main()
{
std::optional<TestStruct> o{ std::nullopt };
std::cout << std::boolalpha << "o.has_value(): " << o.has_value() << o->test() << '\n';
}
W jaki sposób optional
instantyzuje klasę z usuniętym prywatnym konstruktorem?
Dlaczego optional
w ogóle instantyzuje klasę mimo, że:
23.6.3.1 Constructors [optional.ctor]
constexpr optional() noexcept;
constexpr optional(nullopt_t) noexcept;
1 Postconditions: *this does not contain a value.
2 Remarks: No contained value is initialized. For every object type T these constructors shall be constexpr
działający przykład: https://wandbox.org/permlink/YfSO9WGnI2wzyZzX
standard strona 571: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf