Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nonstd::optional is not a literal type #19

Open
maikel opened this issue Jul 27, 2018 · 6 comments
Open

nonstd::optional is not a literal type #19

maikel opened this issue Jul 27, 2018 · 6 comments

Comments

@maikel
Copy link

maikel commented Jul 27, 2018

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 types T. 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, so nonstd::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.

@martinmoene
Copy link
Owner

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:

@martinmoene
Copy link
Owner

See:

@martinmoene
Copy link
Owner

@Kampfzwerg42
Copy link

Kampfzwerg42 commented Jul 23, 2021

Proposal to copy the is_trivially_destructible property for the optional:

  1. replace the destructor of the optional with some normal(protected) member method.
  2. 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;
};

@martinmoene
Copy link
Owner

martinmoene commented Jul 23, 2021

Thanks for your suggestion. May take a couple of weeks before i can address it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants