Deleted implicitly-declared copy assignment operator
up vote
3
down vote
favorite
According to the C++ reference on Copy assignment operator:
A defaulted copy assignment operator for class T is defined as deleted if any of the following is true
T has a non-static data member of non-class type (or array thereof) that is const ...
I was hoping to create a case where I had a const class-type data member and a defaulted copy assignment operator not defined as deleted. In doing so, I found a discrepancy between clang and gcc. Consider the following code:
struct B {
void operator=(const B&) const {}
};
struct A {
const B b{};
A& operator=(const A&) = default;
};
int main() {
A a1{}, a2{};
a1 = a2; //only works with clang
B b1{}, b2{};
b1 = b2; //works in both
}
When I compile this with g++ -std=c++14
I get the following errors:
In member function ‘A& A::operator=(const A&)’:
error: non-static const member ‘const B A::b’, can’t use default assignment operator
note: synthesized method ‘A& A::operator=(const A&)’ first required here
This does, comma, however, compile with clang
, as the reference seems to indicate that it should. Am I in error? Which compiler is correct?
I'm using gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
and clang version 6.0.0-1ubuntu2
.
c++ g++ c++14 clang++ assignment-operator
add a comment |
up vote
3
down vote
favorite
According to the C++ reference on Copy assignment operator:
A defaulted copy assignment operator for class T is defined as deleted if any of the following is true
T has a non-static data member of non-class type (or array thereof) that is const ...
I was hoping to create a case where I had a const class-type data member and a defaulted copy assignment operator not defined as deleted. In doing so, I found a discrepancy between clang and gcc. Consider the following code:
struct B {
void operator=(const B&) const {}
};
struct A {
const B b{};
A& operator=(const A&) = default;
};
int main() {
A a1{}, a2{};
a1 = a2; //only works with clang
B b1{}, b2{};
b1 = b2; //works in both
}
When I compile this with g++ -std=c++14
I get the following errors:
In member function ‘A& A::operator=(const A&)’:
error: non-static const member ‘const B A::b’, can’t use default assignment operator
note: synthesized method ‘A& A::operator=(const A&)’ first required here
This does, comma, however, compile with clang
, as the reference seems to indicate that it should. Am I in error? Which compiler is correct?
I'm using gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
and clang version 6.0.0-1ubuntu2
.
c++ g++ c++14 clang++ assignment-operator
In general you want to useC++
since that gives the question a much wider audience than C++ version specific tags.
– Shafik Yaghmour
Nov 8 at 19:41
add a comment |
up vote
3
down vote
favorite
up vote
3
down vote
favorite
According to the C++ reference on Copy assignment operator:
A defaulted copy assignment operator for class T is defined as deleted if any of the following is true
T has a non-static data member of non-class type (or array thereof) that is const ...
I was hoping to create a case where I had a const class-type data member and a defaulted copy assignment operator not defined as deleted. In doing so, I found a discrepancy between clang and gcc. Consider the following code:
struct B {
void operator=(const B&) const {}
};
struct A {
const B b{};
A& operator=(const A&) = default;
};
int main() {
A a1{}, a2{};
a1 = a2; //only works with clang
B b1{}, b2{};
b1 = b2; //works in both
}
When I compile this with g++ -std=c++14
I get the following errors:
In member function ‘A& A::operator=(const A&)’:
error: non-static const member ‘const B A::b’, can’t use default assignment operator
note: synthesized method ‘A& A::operator=(const A&)’ first required here
This does, comma, however, compile with clang
, as the reference seems to indicate that it should. Am I in error? Which compiler is correct?
I'm using gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
and clang version 6.0.0-1ubuntu2
.
c++ g++ c++14 clang++ assignment-operator
According to the C++ reference on Copy assignment operator:
A defaulted copy assignment operator for class T is defined as deleted if any of the following is true
T has a non-static data member of non-class type (or array thereof) that is const ...
I was hoping to create a case where I had a const class-type data member and a defaulted copy assignment operator not defined as deleted. In doing so, I found a discrepancy between clang and gcc. Consider the following code:
struct B {
void operator=(const B&) const {}
};
struct A {
const B b{};
A& operator=(const A&) = default;
};
int main() {
A a1{}, a2{};
a1 = a2; //only works with clang
B b1{}, b2{};
b1 = b2; //works in both
}
When I compile this with g++ -std=c++14
I get the following errors:
In member function ‘A& A::operator=(const A&)’:
error: non-static const member ‘const B A::b’, can’t use default assignment operator
note: synthesized method ‘A& A::operator=(const A&)’ first required here
This does, comma, however, compile with clang
, as the reference seems to indicate that it should. Am I in error? Which compiler is correct?
I'm using gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
and clang version 6.0.0-1ubuntu2
.
c++ g++ c++14 clang++ assignment-operator
c++ g++ c++14 clang++ assignment-operator
edited Nov 8 at 19:40
Shafik Yaghmour
124k23316520
124k23316520
asked Nov 8 at 18:06
Nathan Chappell
1127
1127
In general you want to useC++
since that gives the question a much wider audience than C++ version specific tags.
– Shafik Yaghmour
Nov 8 at 19:41
add a comment |
In general you want to useC++
since that gives the question a much wider audience than C++ version specific tags.
– Shafik Yaghmour
Nov 8 at 19:41
In general you want to use
C++
since that gives the question a much wider audience than C++ version specific tags.– Shafik Yaghmour
Nov 8 at 19:41
In general you want to use
C++
since that gives the question a much wider audience than C++ version specific tags.– Shafik Yaghmour
Nov 8 at 19:41
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
accepted
It seems that clang is right,
Although not yet confirmed, there is a report on the subject for gcc
and as it was pointed out, the two rules relevant to this case don't apply
[class.copy.assign]/7
(7.2) a non-static data member of const non-class type (or array thereof), or
[...]
(7.4) a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because overload resolution ([over.match]), as applied to find M's corresponding assignment operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted assignment operator.
add a comment |
up vote
1
down vote
It sure looks like clang is correct, section [class.copy.assign]p7 says:
A defaulted copy/move assignment operator for class X is defined as
deleted if X has:
- (7.1) a variant member with a non-trivial corresponding assignment operator and X is a union-like class, or
- (7.2) a non-static data member of const non-class type (or array thereof), or
- (7.3) a non-static data member of reference type, or
- (7.4) a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because
overload resolution ([over.match]), as applied to find M's
corresponding assignment operator, results in an ambiguity or a
function that is deleted or inaccessible from the defaulted assignment
operator.
A defaulted move assignment operator that is defined as deleted is
ignored by overload resolution ([over.match], [over.over]).
and none of those cases hold.
Although I have to say a const copy assignment operator that returns void feels novel, the wording in [class.copy.assign]p1 sure seems to allow.
There is an open gcc bug report for a similar case Const subobject with const assignment operator, but operator anyway deleted with code as follows:
class bar
{
public:
bar() {}
bar const & operator=(bar const &) const
{
return *this;
}
};
class foo
{
bar const v;
};
int main()
{
foo a;
a = foo();
}
The reporter points out the same section as I do.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
It seems that clang is right,
Although not yet confirmed, there is a report on the subject for gcc
and as it was pointed out, the two rules relevant to this case don't apply
[class.copy.assign]/7
(7.2) a non-static data member of const non-class type (or array thereof), or
[...]
(7.4) a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because overload resolution ([over.match]), as applied to find M's corresponding assignment operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted assignment operator.
add a comment |
up vote
1
down vote
accepted
It seems that clang is right,
Although not yet confirmed, there is a report on the subject for gcc
and as it was pointed out, the two rules relevant to this case don't apply
[class.copy.assign]/7
(7.2) a non-static data member of const non-class type (or array thereof), or
[...]
(7.4) a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because overload resolution ([over.match]), as applied to find M's corresponding assignment operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted assignment operator.
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
It seems that clang is right,
Although not yet confirmed, there is a report on the subject for gcc
and as it was pointed out, the two rules relevant to this case don't apply
[class.copy.assign]/7
(7.2) a non-static data member of const non-class type (or array thereof), or
[...]
(7.4) a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because overload resolution ([over.match]), as applied to find M's corresponding assignment operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted assignment operator.
It seems that clang is right,
Although not yet confirmed, there is a report on the subject for gcc
and as it was pointed out, the two rules relevant to this case don't apply
[class.copy.assign]/7
(7.2) a non-static data member of const non-class type (or array thereof), or
[...]
(7.4) a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because overload resolution ([over.match]), as applied to find M's corresponding assignment operator, results in an ambiguity or a function that is deleted or inaccessible from the defaulted assignment operator.
answered Nov 8 at 18:55
Jans
6,68912233
6,68912233
add a comment |
add a comment |
up vote
1
down vote
It sure looks like clang is correct, section [class.copy.assign]p7 says:
A defaulted copy/move assignment operator for class X is defined as
deleted if X has:
- (7.1) a variant member with a non-trivial corresponding assignment operator and X is a union-like class, or
- (7.2) a non-static data member of const non-class type (or array thereof), or
- (7.3) a non-static data member of reference type, or
- (7.4) a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because
overload resolution ([over.match]), as applied to find M's
corresponding assignment operator, results in an ambiguity or a
function that is deleted or inaccessible from the defaulted assignment
operator.
A defaulted move assignment operator that is defined as deleted is
ignored by overload resolution ([over.match], [over.over]).
and none of those cases hold.
Although I have to say a const copy assignment operator that returns void feels novel, the wording in [class.copy.assign]p1 sure seems to allow.
There is an open gcc bug report for a similar case Const subobject with const assignment operator, but operator anyway deleted with code as follows:
class bar
{
public:
bar() {}
bar const & operator=(bar const &) const
{
return *this;
}
};
class foo
{
bar const v;
};
int main()
{
foo a;
a = foo();
}
The reporter points out the same section as I do.
add a comment |
up vote
1
down vote
It sure looks like clang is correct, section [class.copy.assign]p7 says:
A defaulted copy/move assignment operator for class X is defined as
deleted if X has:
- (7.1) a variant member with a non-trivial corresponding assignment operator and X is a union-like class, or
- (7.2) a non-static data member of const non-class type (or array thereof), or
- (7.3) a non-static data member of reference type, or
- (7.4) a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because
overload resolution ([over.match]), as applied to find M's
corresponding assignment operator, results in an ambiguity or a
function that is deleted or inaccessible from the defaulted assignment
operator.
A defaulted move assignment operator that is defined as deleted is
ignored by overload resolution ([over.match], [over.over]).
and none of those cases hold.
Although I have to say a const copy assignment operator that returns void feels novel, the wording in [class.copy.assign]p1 sure seems to allow.
There is an open gcc bug report for a similar case Const subobject with const assignment operator, but operator anyway deleted with code as follows:
class bar
{
public:
bar() {}
bar const & operator=(bar const &) const
{
return *this;
}
};
class foo
{
bar const v;
};
int main()
{
foo a;
a = foo();
}
The reporter points out the same section as I do.
add a comment |
up vote
1
down vote
up vote
1
down vote
It sure looks like clang is correct, section [class.copy.assign]p7 says:
A defaulted copy/move assignment operator for class X is defined as
deleted if X has:
- (7.1) a variant member with a non-trivial corresponding assignment operator and X is a union-like class, or
- (7.2) a non-static data member of const non-class type (or array thereof), or
- (7.3) a non-static data member of reference type, or
- (7.4) a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because
overload resolution ([over.match]), as applied to find M's
corresponding assignment operator, results in an ambiguity or a
function that is deleted or inaccessible from the defaulted assignment
operator.
A defaulted move assignment operator that is defined as deleted is
ignored by overload resolution ([over.match], [over.over]).
and none of those cases hold.
Although I have to say a const copy assignment operator that returns void feels novel, the wording in [class.copy.assign]p1 sure seems to allow.
There is an open gcc bug report for a similar case Const subobject with const assignment operator, but operator anyway deleted with code as follows:
class bar
{
public:
bar() {}
bar const & operator=(bar const &) const
{
return *this;
}
};
class foo
{
bar const v;
};
int main()
{
foo a;
a = foo();
}
The reporter points out the same section as I do.
It sure looks like clang is correct, section [class.copy.assign]p7 says:
A defaulted copy/move assignment operator for class X is defined as
deleted if X has:
- (7.1) a variant member with a non-trivial corresponding assignment operator and X is a union-like class, or
- (7.2) a non-static data member of const non-class type (or array thereof), or
- (7.3) a non-static data member of reference type, or
- (7.4) a direct non-static data member of class type M (or array thereof) or a direct base class M that cannot be copied/moved because
overload resolution ([over.match]), as applied to find M's
corresponding assignment operator, results in an ambiguity or a
function that is deleted or inaccessible from the defaulted assignment
operator.
A defaulted move assignment operator that is defined as deleted is
ignored by overload resolution ([over.match], [over.over]).
and none of those cases hold.
Although I have to say a const copy assignment operator that returns void feels novel, the wording in [class.copy.assign]p1 sure seems to allow.
There is an open gcc bug report for a similar case Const subobject with const assignment operator, but operator anyway deleted with code as follows:
class bar
{
public:
bar() {}
bar const & operator=(bar const &) const
{
return *this;
}
};
class foo
{
bar const v;
};
int main()
{
foo a;
a = foo();
}
The reporter points out the same section as I do.
edited Nov 10 at 23:18
answered Nov 8 at 18:36
Shafik Yaghmour
124k23316520
124k23316520
add a comment |
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2f53213681%2fdeleted-implicitly-declared-copy-assignment-operator%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
In general you want to use
C++
since that gives the question a much wider audience than C++ version specific tags.– Shafik Yaghmour
Nov 8 at 19:41