Declaring defaulted assignment operator as constexpr: which compiler is right?2019 Community Moderator ElectionWhy don't C++ compilers define operator== and operator!=?Different cast operator called by different compilersGCC accepts `constexpr struct s;` but Clang rejects it. Who is correct?Why can't decomposition declarations be constexpr?Deduction guides, templates and subobjects: which compiler is right?C++ constexpr inheriting constructorLambda returning itself: is this legal?`extern` declarations and following defintions of class template instances with and without parameter listscomma operator makes lambda expression non-constexprInconsistent behaviour across compilers in regard to instantiation of a template in a discarded if constexpr(false) statement
Is there a hypothetical scenario that would make Earth uninhabitable for humans, but not for (the majority of) other animals?
I am confused as to how the inverse of a certain function is found.
How to make healing in an exploration game interesting
Do I need to be arrogant to get ahead?
Why does a Star of David appear at a rally with Francisco Franco?
Are relativity and doppler effect related?
What is the Japanese sound word for the clinking of money?
Is it true that good novels will automatically sell themselves on Amazon (and so on) and there is no need for one to waste time promoting?
Knife as defense against stray dogs
What is the significance behind "40 days" that often appears in the Bible?
Fastest way to pop N items from a large dict
Problem with FindRoot
What do you call the act of removing a part of a word and replacing it with an apostrophe
Recruiter wants very extensive technical details about all of my previous work
Why Choose Less Effective Armour Types?
Pauli exclusion principle
Employee lack of ownership
Min function accepting varying number of arguments in C++17
How do I hide Chekhov's Gun?
Why did it take so long to abandon sail after steamships were demonstrated?
Happy pi day, everyone!
Welcoming 2019 Pi day: How to draw the letter π?
What is the adequate fee for a reveal operation?
How to terminate ping <dest> &
Declaring defaulted assignment operator as constexpr: which compiler is right?
2019 Community Moderator ElectionWhy don't C++ compilers define operator== and operator!=?Different cast operator called by different compilersGCC accepts `constexpr struct s;` but Clang rejects it. Who is correct?Why can't decomposition declarations be constexpr?Deduction guides, templates and subobjects: which compiler is right?C++ constexpr inheriting constructorLambda returning itself: is this legal?`extern` declarations and following defintions of class template instances with and without parameter listscomma operator makes lambda expression non-constexprInconsistent behaviour across compilers in regard to instantiation of a template in a discarded if constexpr(false) statement
Consider
struct A1
constexpr A1& operator=(const A1&) = default;
~A1()
;
struct A2
constexpr A2& operator=(const A2&) = default;
~A2() = default;
;
struct A3
~A3() = default;
constexpr A3& operator=(const A3&) = default;
;
GCC and MSVC accept all three structs. Clang rejects A1
and A2
(but accepts A3
), with the following error message:
<source>:2:5: error: defaulted definition of copy assignment operator is not constexpr
constexpr A1& operator=(const A1&) = default;
^
<source>:6:5: error: defaulted definition of copy assignment operator is not constexpr
constexpr A2& operator=(const A2&) = default;
^
2 errors generated.
(live demo)
Which compiler is correct, and why?
c++ language-lawyer c++17 constexpr
add a comment |
Consider
struct A1
constexpr A1& operator=(const A1&) = default;
~A1()
;
struct A2
constexpr A2& operator=(const A2&) = default;
~A2() = default;
;
struct A3
~A3() = default;
constexpr A3& operator=(const A3&) = default;
;
GCC and MSVC accept all three structs. Clang rejects A1
and A2
(but accepts A3
), with the following error message:
<source>:2:5: error: defaulted definition of copy assignment operator is not constexpr
constexpr A1& operator=(const A1&) = default;
^
<source>:6:5: error: defaulted definition of copy assignment operator is not constexpr
constexpr A2& operator=(const A2&) = default;
^
2 errors generated.
(live demo)
Which compiler is correct, and why?
c++ language-lawyer c++17 constexpr
Good question. The following is only a guess... We know thatconstexpr
in functions doesn't meanconst
. It means whether or not that function can be computed at compile time. The silently created copy assignment operator is not preceded by aconstexpr
. This means that theconstexpr
you have is an overload to the silently created one. The overload however cannot be defaulted, which explains the error. Check out the following 3 code examples: 1) (clang) rextester.com/WLGFD87794, 2) (gcc) rextester.com/RMWQ86797, 3) (vc++) rextester.com/MXIHQ50551 .
– Constantinos Glynos
yesterday
add a comment |
Consider
struct A1
constexpr A1& operator=(const A1&) = default;
~A1()
;
struct A2
constexpr A2& operator=(const A2&) = default;
~A2() = default;
;
struct A3
~A3() = default;
constexpr A3& operator=(const A3&) = default;
;
GCC and MSVC accept all three structs. Clang rejects A1
and A2
(but accepts A3
), with the following error message:
<source>:2:5: error: defaulted definition of copy assignment operator is not constexpr
constexpr A1& operator=(const A1&) = default;
^
<source>:6:5: error: defaulted definition of copy assignment operator is not constexpr
constexpr A2& operator=(const A2&) = default;
^
2 errors generated.
(live demo)
Which compiler is correct, and why?
c++ language-lawyer c++17 constexpr
Consider
struct A1
constexpr A1& operator=(const A1&) = default;
~A1()
;
struct A2
constexpr A2& operator=(const A2&) = default;
~A2() = default;
;
struct A3
~A3() = default;
constexpr A3& operator=(const A3&) = default;
;
GCC and MSVC accept all three structs. Clang rejects A1
and A2
(but accepts A3
), with the following error message:
<source>:2:5: error: defaulted definition of copy assignment operator is not constexpr
constexpr A1& operator=(const A1&) = default;
^
<source>:6:5: error: defaulted definition of copy assignment operator is not constexpr
constexpr A2& operator=(const A2&) = default;
^
2 errors generated.
(live demo)
Which compiler is correct, and why?
c++ language-lawyer c++17 constexpr
c++ language-lawyer c++17 constexpr
asked yesterday
cpplearnercpplearner
5,31222241
5,31222241
Good question. The following is only a guess... We know thatconstexpr
in functions doesn't meanconst
. It means whether or not that function can be computed at compile time. The silently created copy assignment operator is not preceded by aconstexpr
. This means that theconstexpr
you have is an overload to the silently created one. The overload however cannot be defaulted, which explains the error. Check out the following 3 code examples: 1) (clang) rextester.com/WLGFD87794, 2) (gcc) rextester.com/RMWQ86797, 3) (vc++) rextester.com/MXIHQ50551 .
– Constantinos Glynos
yesterday
add a comment |
Good question. The following is only a guess... We know thatconstexpr
in functions doesn't meanconst
. It means whether or not that function can be computed at compile time. The silently created copy assignment operator is not preceded by aconstexpr
. This means that theconstexpr
you have is an overload to the silently created one. The overload however cannot be defaulted, which explains the error. Check out the following 3 code examples: 1) (clang) rextester.com/WLGFD87794, 2) (gcc) rextester.com/RMWQ86797, 3) (vc++) rextester.com/MXIHQ50551 .
– Constantinos Glynos
yesterday
Good question. The following is only a guess... We know that
constexpr
in functions doesn't mean const
. It means whether or not that function can be computed at compile time. The silently created copy assignment operator is not preceded by a constexpr
. This means that the constexpr
you have is an overload to the silently created one. The overload however cannot be defaulted, which explains the error. Check out the following 3 code examples: 1) (clang) rextester.com/WLGFD87794, 2) (gcc) rextester.com/RMWQ86797, 3) (vc++) rextester.com/MXIHQ50551 .– Constantinos Glynos
yesterday
Good question. The following is only a guess... We know that
constexpr
in functions doesn't mean const
. It means whether or not that function can be computed at compile time. The silently created copy assignment operator is not preceded by a constexpr
. This means that the constexpr
you have is an overload to the silently created one. The overload however cannot be defaulted, which explains the error. Check out the following 3 code examples: 1) (clang) rextester.com/WLGFD87794, 2) (gcc) rextester.com/RMWQ86797, 3) (vc++) rextester.com/MXIHQ50551 .– Constantinos Glynos
yesterday
add a comment |
2 Answers
2
active
oldest
votes
I think all three compilers are wrong.
[dcl.fct.def.default]/3 says:
An explicitly-defaulted function that is not defined as deleted may be declared
constexpr
orconsteval
only if it would have been implicitly declared asconstexpr
. If a function is explicitly defaulted on its first declaration, it is implicitly considered to beconstexpr
if the implicit declaration would be.
When is the copy assignment operator implicitly declared constexpr
? [class.copy.assign]/10:
The implicitly-defined copy/move assignment operator is constexpr if
- X is a literal type, and
- [...]
Where a literal type is, from [basic.types]/10:
A type is a literal type if it is:
- [...]
a possibly cv-qualified class type that has all of the following properties:
- it has a trivial destructor,
- [...]
A1
doesn't have a trivial destructor, so its implicit copy assignment operator isn't constexpr
. Hence that copy assignment operator is ill-formed (gcc and msvc bug to accept).
The other two are fine, and it's a clang bug to reject A2
.
Note the last bit of [dcl.fct.def.default] that I quoted. You don't actually have to add constexpr
if you're explicitly defaulting. It would be implicitly constexpr
where that is possible.
Addingconstexpr
should give you an error if it isn'tconstexpr
, which is something that could be quite useful.
– Yakk - Adam Nevraumont
yesterday
add a comment |
The C++17 standard states:
15.8.2 Copy/move assignment operator [class.copy.assign]
...
10 A copy/move assignment operator for a class X that is defaulted and not defined as deleted is implicitly defined when it is odr-used (6.2) (e.g., when it is selected by overload resolution to assign to an object of its class type) or when it is explicitly defaulted after its first declaration. The implicitly-defined copy/move assignment operator is
constexpr
if
(10.1) —X
is a literal type, and
(10.2) — the assignment operator selected to copy/move each direct base class subobject is aconstexpr
function, and
(10.3) — for each non-static data member ofX
that is of class type (or array thereof), the assignment operator selected to copy/move that member is aconstexpr
function.
The copy-assignment operator satisfies the above requirements in two of the cases. In the first case, we have a non-literal type because of the non-trivial destructor.
So I believe Clang is wrong to reject the code in the second case.
There is a bug filed with Clang titled: Defaulted destructor prevents using constexpr on defaulted copy/move-operator which shows the same symptoms as the code in the OP.
The comments from the bug report state:
When defaulted destructor is commented out (i.e. not user declared), then errors cease to exist.
and
The problem also goes away if you declare the destructor before the copy assignment operator.
This is true of the code in the question as well.
As @YSC points out, another relevant quote here is:[dcl.fct.def.default]/3 which states:
An explicitly-defaulted function that is not defined as deleted may be declared
constexpr
orconsteval
only if it would have been implicitly declared asconstexpr
. If a function is explicitly defaulted on its first declaration, it is implicitly considered to beconstexpr
if the implicit declaration would be.
related: eel.is/c++draft/dcl.fct.def.default#3 and eel.is/c++draft/class.copy.assign#10 (already quoted)
– YSC
yesterday
May I translate this into: Changing the order of destructor and copy assignment definition (like OP did forstruct A2
andstruct A3
) shouldn't have any effect (for compiling the code without error)?
– Scheff
yesterday
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55182242%2fdeclaring-defaulted-assignment-operator-as-constexpr-which-compiler-is-right%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think all three compilers are wrong.
[dcl.fct.def.default]/3 says:
An explicitly-defaulted function that is not defined as deleted may be declared
constexpr
orconsteval
only if it would have been implicitly declared asconstexpr
. If a function is explicitly defaulted on its first declaration, it is implicitly considered to beconstexpr
if the implicit declaration would be.
When is the copy assignment operator implicitly declared constexpr
? [class.copy.assign]/10:
The implicitly-defined copy/move assignment operator is constexpr if
- X is a literal type, and
- [...]
Where a literal type is, from [basic.types]/10:
A type is a literal type if it is:
- [...]
a possibly cv-qualified class type that has all of the following properties:
- it has a trivial destructor,
- [...]
A1
doesn't have a trivial destructor, so its implicit copy assignment operator isn't constexpr
. Hence that copy assignment operator is ill-formed (gcc and msvc bug to accept).
The other two are fine, and it's a clang bug to reject A2
.
Note the last bit of [dcl.fct.def.default] that I quoted. You don't actually have to add constexpr
if you're explicitly defaulting. It would be implicitly constexpr
where that is possible.
Addingconstexpr
should give you an error if it isn'tconstexpr
, which is something that could be quite useful.
– Yakk - Adam Nevraumont
yesterday
add a comment |
I think all three compilers are wrong.
[dcl.fct.def.default]/3 says:
An explicitly-defaulted function that is not defined as deleted may be declared
constexpr
orconsteval
only if it would have been implicitly declared asconstexpr
. If a function is explicitly defaulted on its first declaration, it is implicitly considered to beconstexpr
if the implicit declaration would be.
When is the copy assignment operator implicitly declared constexpr
? [class.copy.assign]/10:
The implicitly-defined copy/move assignment operator is constexpr if
- X is a literal type, and
- [...]
Where a literal type is, from [basic.types]/10:
A type is a literal type if it is:
- [...]
a possibly cv-qualified class type that has all of the following properties:
- it has a trivial destructor,
- [...]
A1
doesn't have a trivial destructor, so its implicit copy assignment operator isn't constexpr
. Hence that copy assignment operator is ill-formed (gcc and msvc bug to accept).
The other two are fine, and it's a clang bug to reject A2
.
Note the last bit of [dcl.fct.def.default] that I quoted. You don't actually have to add constexpr
if you're explicitly defaulting. It would be implicitly constexpr
where that is possible.
Addingconstexpr
should give you an error if it isn'tconstexpr
, which is something that could be quite useful.
– Yakk - Adam Nevraumont
yesterday
add a comment |
I think all three compilers are wrong.
[dcl.fct.def.default]/3 says:
An explicitly-defaulted function that is not defined as deleted may be declared
constexpr
orconsteval
only if it would have been implicitly declared asconstexpr
. If a function is explicitly defaulted on its first declaration, it is implicitly considered to beconstexpr
if the implicit declaration would be.
When is the copy assignment operator implicitly declared constexpr
? [class.copy.assign]/10:
The implicitly-defined copy/move assignment operator is constexpr if
- X is a literal type, and
- [...]
Where a literal type is, from [basic.types]/10:
A type is a literal type if it is:
- [...]
a possibly cv-qualified class type that has all of the following properties:
- it has a trivial destructor,
- [...]
A1
doesn't have a trivial destructor, so its implicit copy assignment operator isn't constexpr
. Hence that copy assignment operator is ill-formed (gcc and msvc bug to accept).
The other two are fine, and it's a clang bug to reject A2
.
Note the last bit of [dcl.fct.def.default] that I quoted. You don't actually have to add constexpr
if you're explicitly defaulting. It would be implicitly constexpr
where that is possible.
I think all three compilers are wrong.
[dcl.fct.def.default]/3 says:
An explicitly-defaulted function that is not defined as deleted may be declared
constexpr
orconsteval
only if it would have been implicitly declared asconstexpr
. If a function is explicitly defaulted on its first declaration, it is implicitly considered to beconstexpr
if the implicit declaration would be.
When is the copy assignment operator implicitly declared constexpr
? [class.copy.assign]/10:
The implicitly-defined copy/move assignment operator is constexpr if
- X is a literal type, and
- [...]
Where a literal type is, from [basic.types]/10:
A type is a literal type if it is:
- [...]
a possibly cv-qualified class type that has all of the following properties:
- it has a trivial destructor,
- [...]
A1
doesn't have a trivial destructor, so its implicit copy assignment operator isn't constexpr
. Hence that copy assignment operator is ill-formed (gcc and msvc bug to accept).
The other two are fine, and it's a clang bug to reject A2
.
Note the last bit of [dcl.fct.def.default] that I quoted. You don't actually have to add constexpr
if you're explicitly defaulting. It would be implicitly constexpr
where that is possible.
answered yesterday
BarryBarry
184k21324595
184k21324595
Addingconstexpr
should give you an error if it isn'tconstexpr
, which is something that could be quite useful.
– Yakk - Adam Nevraumont
yesterday
add a comment |
Addingconstexpr
should give you an error if it isn'tconstexpr
, which is something that could be quite useful.
– Yakk - Adam Nevraumont
yesterday
Adding
constexpr
should give you an error if it isn't constexpr
, which is something that could be quite useful.– Yakk - Adam Nevraumont
yesterday
Adding
constexpr
should give you an error if it isn't constexpr
, which is something that could be quite useful.– Yakk - Adam Nevraumont
yesterday
add a comment |
The C++17 standard states:
15.8.2 Copy/move assignment operator [class.copy.assign]
...
10 A copy/move assignment operator for a class X that is defaulted and not defined as deleted is implicitly defined when it is odr-used (6.2) (e.g., when it is selected by overload resolution to assign to an object of its class type) or when it is explicitly defaulted after its first declaration. The implicitly-defined copy/move assignment operator is
constexpr
if
(10.1) —X
is a literal type, and
(10.2) — the assignment operator selected to copy/move each direct base class subobject is aconstexpr
function, and
(10.3) — for each non-static data member ofX
that is of class type (or array thereof), the assignment operator selected to copy/move that member is aconstexpr
function.
The copy-assignment operator satisfies the above requirements in two of the cases. In the first case, we have a non-literal type because of the non-trivial destructor.
So I believe Clang is wrong to reject the code in the second case.
There is a bug filed with Clang titled: Defaulted destructor prevents using constexpr on defaulted copy/move-operator which shows the same symptoms as the code in the OP.
The comments from the bug report state:
When defaulted destructor is commented out (i.e. not user declared), then errors cease to exist.
and
The problem also goes away if you declare the destructor before the copy assignment operator.
This is true of the code in the question as well.
As @YSC points out, another relevant quote here is:[dcl.fct.def.default]/3 which states:
An explicitly-defaulted function that is not defined as deleted may be declared
constexpr
orconsteval
only if it would have been implicitly declared asconstexpr
. If a function is explicitly defaulted on its first declaration, it is implicitly considered to beconstexpr
if the implicit declaration would be.
related: eel.is/c++draft/dcl.fct.def.default#3 and eel.is/c++draft/class.copy.assign#10 (already quoted)
– YSC
yesterday
May I translate this into: Changing the order of destructor and copy assignment definition (like OP did forstruct A2
andstruct A3
) shouldn't have any effect (for compiling the code without error)?
– Scheff
yesterday
add a comment |
The C++17 standard states:
15.8.2 Copy/move assignment operator [class.copy.assign]
...
10 A copy/move assignment operator for a class X that is defaulted and not defined as deleted is implicitly defined when it is odr-used (6.2) (e.g., when it is selected by overload resolution to assign to an object of its class type) or when it is explicitly defaulted after its first declaration. The implicitly-defined copy/move assignment operator is
constexpr
if
(10.1) —X
is a literal type, and
(10.2) — the assignment operator selected to copy/move each direct base class subobject is aconstexpr
function, and
(10.3) — for each non-static data member ofX
that is of class type (or array thereof), the assignment operator selected to copy/move that member is aconstexpr
function.
The copy-assignment operator satisfies the above requirements in two of the cases. In the first case, we have a non-literal type because of the non-trivial destructor.
So I believe Clang is wrong to reject the code in the second case.
There is a bug filed with Clang titled: Defaulted destructor prevents using constexpr on defaulted copy/move-operator which shows the same symptoms as the code in the OP.
The comments from the bug report state:
When defaulted destructor is commented out (i.e. not user declared), then errors cease to exist.
and
The problem also goes away if you declare the destructor before the copy assignment operator.
This is true of the code in the question as well.
As @YSC points out, another relevant quote here is:[dcl.fct.def.default]/3 which states:
An explicitly-defaulted function that is not defined as deleted may be declared
constexpr
orconsteval
only if it would have been implicitly declared asconstexpr
. If a function is explicitly defaulted on its first declaration, it is implicitly considered to beconstexpr
if the implicit declaration would be.
related: eel.is/c++draft/dcl.fct.def.default#3 and eel.is/c++draft/class.copy.assign#10 (already quoted)
– YSC
yesterday
May I translate this into: Changing the order of destructor and copy assignment definition (like OP did forstruct A2
andstruct A3
) shouldn't have any effect (for compiling the code without error)?
– Scheff
yesterday
add a comment |
The C++17 standard states:
15.8.2 Copy/move assignment operator [class.copy.assign]
...
10 A copy/move assignment operator for a class X that is defaulted and not defined as deleted is implicitly defined when it is odr-used (6.2) (e.g., when it is selected by overload resolution to assign to an object of its class type) or when it is explicitly defaulted after its first declaration. The implicitly-defined copy/move assignment operator is
constexpr
if
(10.1) —X
is a literal type, and
(10.2) — the assignment operator selected to copy/move each direct base class subobject is aconstexpr
function, and
(10.3) — for each non-static data member ofX
that is of class type (or array thereof), the assignment operator selected to copy/move that member is aconstexpr
function.
The copy-assignment operator satisfies the above requirements in two of the cases. In the first case, we have a non-literal type because of the non-trivial destructor.
So I believe Clang is wrong to reject the code in the second case.
There is a bug filed with Clang titled: Defaulted destructor prevents using constexpr on defaulted copy/move-operator which shows the same symptoms as the code in the OP.
The comments from the bug report state:
When defaulted destructor is commented out (i.e. not user declared), then errors cease to exist.
and
The problem also goes away if you declare the destructor before the copy assignment operator.
This is true of the code in the question as well.
As @YSC points out, another relevant quote here is:[dcl.fct.def.default]/3 which states:
An explicitly-defaulted function that is not defined as deleted may be declared
constexpr
orconsteval
only if it would have been implicitly declared asconstexpr
. If a function is explicitly defaulted on its first declaration, it is implicitly considered to beconstexpr
if the implicit declaration would be.
The C++17 standard states:
15.8.2 Copy/move assignment operator [class.copy.assign]
...
10 A copy/move assignment operator for a class X that is defaulted and not defined as deleted is implicitly defined when it is odr-used (6.2) (e.g., when it is selected by overload resolution to assign to an object of its class type) or when it is explicitly defaulted after its first declaration. The implicitly-defined copy/move assignment operator is
constexpr
if
(10.1) —X
is a literal type, and
(10.2) — the assignment operator selected to copy/move each direct base class subobject is aconstexpr
function, and
(10.3) — for each non-static data member ofX
that is of class type (or array thereof), the assignment operator selected to copy/move that member is aconstexpr
function.
The copy-assignment operator satisfies the above requirements in two of the cases. In the first case, we have a non-literal type because of the non-trivial destructor.
So I believe Clang is wrong to reject the code in the second case.
There is a bug filed with Clang titled: Defaulted destructor prevents using constexpr on defaulted copy/move-operator which shows the same symptoms as the code in the OP.
The comments from the bug report state:
When defaulted destructor is commented out (i.e. not user declared), then errors cease to exist.
and
The problem also goes away if you declare the destructor before the copy assignment operator.
This is true of the code in the question as well.
As @YSC points out, another relevant quote here is:[dcl.fct.def.default]/3 which states:
An explicitly-defaulted function that is not defined as deleted may be declared
constexpr
orconsteval
only if it would have been implicitly declared asconstexpr
. If a function is explicitly defaulted on its first declaration, it is implicitly considered to beconstexpr
if the implicit declaration would be.
edited yesterday
answered yesterday
P.WP.W
16.7k41455
16.7k41455
related: eel.is/c++draft/dcl.fct.def.default#3 and eel.is/c++draft/class.copy.assign#10 (already quoted)
– YSC
yesterday
May I translate this into: Changing the order of destructor and copy assignment definition (like OP did forstruct A2
andstruct A3
) shouldn't have any effect (for compiling the code without error)?
– Scheff
yesterday
add a comment |
related: eel.is/c++draft/dcl.fct.def.default#3 and eel.is/c++draft/class.copy.assign#10 (already quoted)
– YSC
yesterday
May I translate this into: Changing the order of destructor and copy assignment definition (like OP did forstruct A2
andstruct A3
) shouldn't have any effect (for compiling the code without error)?
– Scheff
yesterday
related: eel.is/c++draft/dcl.fct.def.default#3 and eel.is/c++draft/class.copy.assign#10 (already quoted)
– YSC
yesterday
related: eel.is/c++draft/dcl.fct.def.default#3 and eel.is/c++draft/class.copy.assign#10 (already quoted)
– YSC
yesterday
May I translate this into: Changing the order of destructor and copy assignment definition (like OP did for
struct A2
and struct A3
) shouldn't have any effect (for compiling the code without error)?– Scheff
yesterday
May I translate this into: Changing the order of destructor and copy assignment definition (like OP did for
struct A2
and struct A3
) shouldn't have any effect (for compiling the code without error)?– Scheff
yesterday
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55182242%2fdeclaring-defaulted-assignment-operator-as-constexpr-which-compiler-is-right%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Good question. The following is only a guess... We know that
constexpr
in functions doesn't meanconst
. It means whether or not that function can be computed at compile time. The silently created copy assignment operator is not preceded by aconstexpr
. This means that theconstexpr
you have is an overload to the silently created one. The overload however cannot be defaulted, which explains the error. Check out the following 3 code examples: 1) (clang) rextester.com/WLGFD87794, 2) (gcc) rextester.com/RMWQ86797, 3) (vc++) rextester.com/MXIHQ50551 .– Constantinos Glynos
yesterday