是否始终声明特殊成员函数? [英] Are the special member functions always declared?
问题描述
在标准的§12中,每个特殊成员函数都有一组规则,使它隐含地声明为默认
和另一组规则,导致一个默认的[特殊成员函数]定义为删除
。
In §12 of the standard every special member function has a set of rules which cause it to be implicitly declared as defaulted
and another set of rules which cause a defaulted [special member function to be] defined as deleted
.
这看起来(对我来说)当特殊成员函数没有用户声明的版本时,有3种潜在状态:decl和defined( defaulted
),decland undefined( deleted
)和undeclared。这是准确吗?
This makes it seem (to me) that there are 3 potential states when no user-declared version is present for special member functions: declared and defined (defaulted
), declared and undefined (deleted
), and undeclared. Is this accurate? If so, what point is there as opposed to cutting out the 'undeclared' option?
* 声明为默认值
似乎是一个错误,应该不是定义作为默认值?
* declared as defaulted
seems like a mistake, shouldn't it be "defined" as defaulted?
推荐答案
在被删除的构造函数和隐式未声明的构造函数之间是被删除的构造函数参与重载解析,而不存在的构造函数不参与重载解析。
The difference between a deleted constructor and an implicitly undeclared constructor is that the deleted constructor participates in overload resolution, whereas the constructor that doesn't exist, doesn't participate in overload resolution.
示例:
此类是默认可构造的。编译器不会隐式声明一个默认的构造函数。
This class is default constructible. The compiler does not implicitly declare a defaulted constructor for it.
struct A
{
template <class ...T>
A(T...) {}
};
int main()
{
A a; // ok
}
如果编译器声明了一个默认构造函数,默认构造函数定义为已删除,那么 A
不会是默认可构造的。这可以模拟:
If the compiler did declare a default constructor for it, and if that default constructor was defined as deleted, then A
would not be default constructible. That can be simulated with:
struct A
{
A() = delete; // pretend the compiler implicitly declared and defined this
template <class ...T>
A(T...) {}
};
int main()
{
A a;
}
error: call to deleted constructor of 'A'
A a;
^
move构造函数中出现类似问题。如果编译器决定隐式声明它并将其定义为已删除,那么即使它有一个可行的拷贝构造函数,也不能从一个右值构造这样的类:
Similar problems appear with the move constructor. If the compiler decides to implicitly declare it and define it as deleted, then one can not construct such a class from an rvalue, even if it has a viable copy constructor:
#include <type_traits>
struct A
{
A();
A(const A&);
A(A&&) = delete; // pretend compiler declared and defined
};
int main()
{
A a = std::declval<A>();
}
error: call to deleted constructor of 'A'
A a = std::declval<A>();
^ ~~~~~~~~~~~~~~~~~
但是如果编译器不隐含地声明一个删除的移动构造函数,则事情只是工作:
But if the compiler does not implicitly declare a deleted move constructor, then things just work:
#include <type_traits>
struct A
{
A();
A(const A&);
};
int main()
{
A a = std::declval<A>(); // ok
}
实际上,如果编译器隐式声明一个删除的移动构造函数 A
,在C ++ 11中重新编译时会出现大量的破解的C ++ 98/03代码! : - )
Indeed, if the compiler did implicitly declare a deleted move constructor for A
, there would be a awful lot of broken C++98/03 code when recompiled in C++11! :-)
这篇关于是否始终声明特殊成员函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!