optional-lite
optional-lite copied to clipboard
nonstd::optional is not a literal type
I am looking for C++14 optional drop-in which I can use in constexpr
contexts. From the Readme it seems to fit my needs, because you state this implementation provides a LiteralType in that case. I tried to compile
int main()
{
constexpr nonstd::optional<int> o = 2;
}
with std=c++14
two different compilers (gcc-8 and clang-5) and both failed to compile the code.
While trying to fix the issue with custom patches I encountered following problems:
To make the type satisfy std::is_literal_type
(deprecated, I know)
- I had to make the destructor of
optional
trivial for trivially destructible typesT
. This can be achieved by inheriting from a base class and using a template specialization. - I had to mark at least on constructor of storage
constexpr
To make the type usuable in constexpr contexts:
- placement new in
storage_t
is not constexpr, sononstd::optional
with this storage implementation is not going to be usable in constexpr contexts.
Did i misunderstand something terribly wrong and/or do you think it would be worthwhile to provide some patches to target the above points.
Thanks for your analysis,
Indeed nonstd::optional
may have been intended to be a literal type under C++11/14, but clearly is not so now (as tests would have revealed :(.
To note: your example does compile with std::optional.
I'd welcome improvements you suggest to constexpr
-ness of nonstd::optional
.
See also:
- Andrzej Krzemieński. optional (nullable) objects for C++14. Reference implementation.
- Simon Brand. C++11/14/17 std::optional with functional-style extensions..
See:
Proposal to copy the is_trivially_destructible property for the optional:
- replace the destructor of the optional with some normal(protected) member method.
- replace the "using optional_lite::optional" with:
class optional_destruction_helper : public optional_lite::optional<T>
{
using optional_lite_base= optional_lite::optional<T>;
public:
using optional_lite_base::optional_lite_base;
};
template<typename T>
class optional_destruction_helper <T, true> : public optional_lite::optional<T>
{
using optional_lite_base= optional_lite::optional<T>;
public:
using optional_lite_base::optional_lite_base;
~optional_destruction_helper ()
{
optional_lite_base::destroy();
}
};
template<typename T>
class optional : public optional_destruction_helper <T, !std::is_trivially_destructible<T>::value>
{
using optional_lite_base= optional_destruction_helper <T, !std::is_trivially_destructible<T>::value>;
public:
using optional_lite_base::optional_lite_base;
};
Thanks for your suggestion. May take a couple of weeks before i can address it.