Considering the following code
struct S
{
constexpr S() { ; }
constexpr S(S const &) { ; }
constexpr S(S &) { ; }
constexpr S(S &&) { ; }
#if 1
S & operator = (S const &) = default;
S & operator = (S &) = default;
S & operator = (S &&) = default;
#else
constexpr S & operator = (S const &) = default;
constexpr S & operator = (S &) = default;
constexpr S & operator = (S &&) = default;
#endif
~S() = default;
};
struct U
{
union
{
S s;
};
constexpr U() : s{} { ; }
};
inline constexpr bool test()
{
U v;
U w;
v = w;
return true;
}
static_assert(test());
I found out that there is contradiction.
I want to use union
(or euqally union-like class) in constexpr
.
Version #if 1
gives an error:
main.cpp:31:23: error: constexpr function never produces a constant expression [-Winvalid-constexpr]
inline constexpr bool test()
^
main.cpp:35:7: note: non-constexpr function 'operator=' cannot be used in a constant expression
v = w;
^
main.cpp:19:8: note: declared here
struct U
^
main.cpp:39:15: error: static_assert expression is not an integral constant expression
static_assert(test());
^~~~~~
main.cpp:35:7: note: non-constexpr function 'operator=' cannot be used in a constant expression
v = w;
^
main.cpp:39:15: note: in call to 'test()'
static_assert(test());
^
main.cpp:19:8: note: declared here
struct U
^
2 errors generated.
But version #if 0
also give an error (error: defaulted definition of copy assignment operator is not constexpr
):
main.cpp:12:5: error: defaulted definition of copy assignment operator is not constexpr
constexpr S & operator = (S const &) = default;
^
main.cpp:13:5: error: defaulted definition of copy assignment operator is not constexpr
constexpr S & operator = (S &) = default;
^
main.cpp:14:5: error: defaulted definition of move assignment operator is not constexpr
constexpr S & operator = (S &&) = default;
^
main.cpp:35:7: error: object of type 'U' cannot be assigned because its copy assignment operator is implicitly deleted
v = w;
^
main.cpp:24:11: note: copy assignment operator of 'U' is implicitly deleted because field 's' has no copy assignment operator
S s;
^
4 errors generated.
All above is for version of clang 3.7.0
, but newer version clang 3.8.0 (trunk 253951)
nothing says about constexpr S & operator = (S const &) = default;
, but consequences are the same.
For trivial copy/move-constructors, but user-provided assignment operators analogous code (construction) compiles fine.
Aucun commentaire:
Enregistrer un commentaire