在标准的第12节中,每个特殊成员函数都有一组导致它implicitly declared as defaulted的规则和另一组导致的规则a defaulted [special member function to be] defined as deleted.
这使得(对我而言)当特殊成员函数没有用户声明的版本时,有3种可能的状态:声明和定义(defaulted),声明和未定义(deleted),以及未声明.这准确吗?如果是这样,有什么意义,而不是削减'未申报'选项?
*declared as defaulted似乎是一个错误,不应该被"定义"为违约吗?
删除的构造函数和隐式未声明的构造函数之间的区别在于已删除的构造函数参与重载解析,而不存在的构造函数不参与重载解析.
例:
此类是默认可构造的.编译器不会隐式声明它的默认构造函数.
struct A
{
template <class ...T>
A(T...) {}
};
int main()
{
A a; // ok
}
Run Code Online (Sandbox Code Playgroud)
如果编译器确实为它声明了一个默认构造函数,并且该默认构造函数被定义为已删除,那么A它将不是默认的可构造函数.可以模拟:
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;
^
Run Code Online (Sandbox Code Playgroud)
移动构造函数出现类似的问题.如果编译器决定隐式声明它并将其定义为已删除,则无法从rvalue构造这样的类,即使它具有可行的复制构造函数:
#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>();
^ ~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
但是如果编译器没有隐式声明一个已删除的移动构造函数,那么事情就会起作用:
#include <type_traits>
struct A
{
A();
A(const A&);
};
int main()
{
A a = std::declval<A>(); // ok
}
Run Code Online (Sandbox Code Playgroud)
事实上,如果编译器也隐式声明已删除的举动构造函数A,就在C++编译11时是非常多的碎C++ 98/03码!:-)
| 归档时间: |
|
| 查看次数: |
343 次 |
| 最近记录: |