删除了隐式声明的复制赋值运算符
Deleted implicitly-declared copy assignment operator
根据 Copy assignment operator 上的 C++ 参考:
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 ...
我希望创建一个案例,其中我有一个 const class 类型的数据成员和一个未定义为已删除的默认复制赋值运算符。在这样做的过程中,我发现了 clang 和 gcc 之间的差异。考虑以下代码:
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
}
当我用 g++ -std=c++14
编译时,出现以下错误:
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
逗号确实如此,但是,使用 clang
编译,因为参考似乎表明它应该。我错了吗?哪个编译器是正确的?
我正在使用 gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
和 clang version 6.0.0-1ubuntu2
。
看起来 clang 确实是正确的,第 [class.copy.assign]p7 节说:
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]).
和 none 这些情况成立。
虽然不得不说一个const复制赋值运算符returnsvoid感觉很新奇,但是[class.copy.assign]p1中的措辞似乎确实允许。
有一个类似案例的公开 gcc 错误报告Const subobject with const assignment operator, but operator anyway deleted,代码如下:
class bar
{
public:
bar() {}
bar const & operator=(bar const &) const
{
return *this;
}
};
class foo
{
bar const v;
};
int main()
{
foo a;
a = foo();
}
记者指的是和我一样的版块
看来clang说的对,
虽然尚未确认,但关于 gcc 的主题有 report
正如所指出的那样,与本案相关的两条规则不适用
(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.
根据 Copy assignment operator 上的 C++ 参考:
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 ...
我希望创建一个案例,其中我有一个 const class 类型的数据成员和一个未定义为已删除的默认复制赋值运算符。在这样做的过程中,我发现了 clang 和 gcc 之间的差异。考虑以下代码:
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
}
当我用 g++ -std=c++14
编译时,出现以下错误:
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
逗号确实如此,但是,使用 clang
编译,因为参考似乎表明它应该。我错了吗?哪个编译器是正确的?
我正在使用 gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
和 clang version 6.0.0-1ubuntu2
。
看起来 clang 确实是正确的,第 [class.copy.assign]p7 节说:
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]).
和 none 这些情况成立。
虽然不得不说一个const复制赋值运算符returnsvoid感觉很新奇,但是[class.copy.assign]p1中的措辞似乎确实允许。
有一个类似案例的公开 gcc 错误报告Const subobject with const assignment operator, but operator anyway deleted,代码如下:
class bar
{
public:
bar() {}
bar const & operator=(bar const &) const
{
return *this;
}
};
class foo
{
bar const v;
};
int main()
{
foo a;
a = foo();
}
记者指的是和我一样的版块
看来clang说的对,
虽然尚未确认,但关于 gcc 的主题有 report 正如所指出的那样,与本案相关的两条规则不适用
(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.