-
Notifications
You must be signed in to change notification settings - Fork 69
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
constexpr moves #35
Comments
2015-11-03 17:15 GMT+01:00 Johannes Laire [email protected]:
An interesting question. The requirements for the constexpr constructor optional(optional&& rhs) noexcept(is_nothrow_move_constructible::value) Can the body of the constexpr constructor alter the value of class members? Regards, |
Thanks for the reply. I have to admit that this stuff is a little bit out of my depth. Perhaps guaranteed copy elision will resolve this for C++17 even if the move ctor can't be constexpr. g++'s behavior might be a bug though. Since a non-movable type can't be returned by value from a function, it would make sense that a non-constexpr-movable type can't be returned by value from a constexpr function. |
I am not sure if it helps anything in practice, but you can return non-moveable types by value with a bit of effort: #include <cassert>
struct Guard
{
int v;
Guard(const Guard&) = delete;
Guard(Guard&&) = delete;
};
Guard makeGuard()
{
return {7};
}
int main()
{
Guard&& g = makeGuard();
assert (g.v == 7);
} You can try it out: |
The same is true for the copy-constructor, it is also not constexpr. IMO, the whole optional interface should be constexpr for literal types(*). The best way to achieve it would be to special-case OptionalBase for literal types. (*) Ideally one should special case copy-constructor, move-constructor, destructor, constructor... depending on whether the type is trivially copy-constructible/moveconstructible/destructible/constructibole/... but this explodes into a mess of base classes. I would say, keep it simple. Make the whole optional interface conditionally constexpr and leave to the OptionalBase class whether the tricky operations (destruction, copy/move construction/assignment) are actually constexpr. Then just specialize the base-class once for literal types. Omit the destructor in the specialization (constexpr destructors must be implicitly generated), and omit the use of placement new in the other operations. Having to special-case OptionalBase for literal/non-literal types is not optimal, but it is the best we can do in C++11, and doing so in C++14 is actually easy as long as one does not need placement new/reinterpret cast, and/or initializer_lists. |
Yes, it should be doable. |
Optional is awesome and I'd like to return an
optional<int>
from a constexpr function. The following function compiles with g++ 5.2.0, but not with clang 3.7.0.I found a mention of this in the rationale:
If optionals can't be returned, their usefulness in constexpr functions seems unfortunately very limited to me.
As a temporary workaround, I tried adding
constexpr
to the move constructor, and both g++ and clang accepted it. Has the definition of constexpr functions been relaxed so that this is possible, or am I relying on overly permissible compilers?The text was updated successfully, but these errors were encountered: