Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++17 make_optional constexpr-ness

Tags:

c++

std

c++17

This page says that the make_optional function in C++17 returns a constexpr optional<...>. I think (I might be wrong though) this would require that optional<T> has a constexpr copy or move constructor. However, this page also says that's not the case.

I don't know how make_optional can be implemented as the C++1z draft currently stands. See this post for clarification. Is there some workaround, or maybe it's just the standard draft/cppreference's mistake?

like image 536
Zizheng Tai Avatar asked Jun 21 '16 00:06

Zizheng Tai


1 Answers

Thanks to @Yakk and @T.C. for their explanations. I feel an example should make things clearer:

struct wrapper {
    int value;

    // non-explicit constexpr constructor
    constexpr wrapper(int v) noexcept : value(v) {}

    // non-constexpr copy & move constructors
    wrapper(const wrapper& that) noexcept : value(that.value) {}
    wrapper(wrapper&& that) noexcept : value(that.value) {}
};

constexpr wrapper make_wrapper(int v)
{
    return {v};
}

int main()
{
    constexpr auto x = make_wrapper(123);  // error! copy/move construction,
                                           // but no constexpr copy/move ctor

    constexpr int y = make_wrapper(123).value;  // ok
    static_assert(y == 123, "");                // passed
}

So make_wrapper does successfully return a constexpr wrapper; it's the copy/move construction (although usually elided by compilers) that prevents the code from compiling, since there is no constexpr copy/move constructor.

We can verify the constexpr-ness of the returned (temporary) wrapper object by using its member value to initialize a constexpr variable.

like image 137
Zizheng Tai Avatar answered Sep 18 '22 15:09

Zizheng Tai