C++11 中已删除成员函数的确切语义是什么?
What's the exact semantics of deleted member functions in C++11?
struct A
{
A();
A(const A&);
A& operator =(const A&);
A(A&&) = delete;
A& operator =(A&&) = delete;
};
struct B
{
B();
B(const B&);
B& operator =(const B&);
};
int main()
{
A a;
a = A(); // error C2280
B b;
b = B(); // OK
}
我的编译器是VC++ 2013 RC。
错误 C2280:"A &A::运算符 =(A &&(":尝试引用 已删除功能
我只是想知道为什么编译器在删除A& operator =(A&&)
时不尝试A& operator =(const A&);
?
此行为是否由C++标准定义?
a = A(); // error C2280
右侧的表达式是临时的,这意味着它将查找operator=(A&&)
并看到它被删除。因此错误。没有进一步的搜索。
=delete
并不意味着">不要使用我,而是使用下一个最好的"。相反,它的意思是,">当你需要我的时候,不要使用我——而是独自一人在野外。
这是另一个例子。如果我希望我的类X
的实例只用long
而没有其他类型(即使它转换为long!(,那么我会class X
声明为:
struct X
{
X(long arg); //ONLY long - NO int, short, char, double, etc!
template<typename T>
X(T) = delete;
};
X a(1); //error - 1 is int
X b(1L); //ok - 1L is long
这意味着,重载解析是在编译器看到=delete
部分之前执行的,因此会导致错误,因为发现选定的重载被删除。
当你=delete
一个函数时,你实际上是在删除它的定义。
8.4.3 删除的定义
1 形式的函数定义:
属性-说明符-seqopt decl-specifier-seqopt declarator = delete ;
称为已删除定义。具有已删除定义的函数也称为已删除函数。
但是,通过这样做,您也声明了该函数。引用标准 [1]:
4 已删除的函数是隐式内联的。[ 注:单一定义规则(3.2(适用于已删除的定义。 —尾注 ] 删除的函数定义应为函数的第一个声明 [...]
因此,通过执行a = A()
,编译器实际上解析为A::operator=(A&&)
,因为它已被声明(不是A::operator(const A&)
,因为A&&
对r值"更具约束力"(。但是,由于删除了其定义,该行的格式不正确。
2 隐式或显式引用已删除函数(而不是声明它(的程序格式不正确。
[1] 这里强调的句子的语气实际上是命令性的。该标准指示声明函数=delete
d必须首先出现在它的其他声明之前。但是,它仍然支持删除函数也会声明该函数的事实。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- C++避免重复声明的语法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 在C++17中,引用const字符串的语义应该是什么
- 在C++中使用移动语义的正确方法是什么?
- 函数作为变量的语义是什么 C++.
- testb $1, %al 的语义是什么
- 模板化代码的语法和语义是什么C++
- C++11 中已删除成员函数的确切语义是什么?
- 消除默认/删除移动/复制语义中涉及的样板的好方法是什么
- 在共享库中全局声明的非pod对象的语义是什么?
- 语义和顶点布局在D3D11中的意义是什么?
- 移动语义 - 它的全部内容是什么?
- 指向已分配对象的指针没有值语义是什么意思
- 在遵循pimpl设计模式的类中实现move语义的正确方法是什么?
- 我是否正确地使用了move语义?好处是什么?
- "值语义"和"指针语义"是什么意思