xml*_*lmx 45 c++ overloading language-lawyer c++11 semantics
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
}
Run Code Online (Sandbox Code Playgroud)
我的编译器是VC++ 2013 RC.
错误C2280:'A&A :: operator =(A &&)':尝试引用已删除的函数
我只是想知道为什么编译器A& operator =(const A&);
在A& operator =(A&&)
删除时不会尝试?
这种行为是由C++标准定义的吗?
Naw*_*waz 70
a = A(); // error C2280
Run Code Online (Sandbox Code Playgroud)
右边的表达式是临时的,这意味着它将查找operator=(A&&)
并看到它被删除.因此错误.没有进一步的搜索.
=delete
也不会意味着"不要用我,而是使用下一个最好的之一".这意味着," 当你需要我的时候不要用我 - 而是在野外独处."
这是另一个例子.如果我想我的类的实例X
,以仅创建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
Run Code Online (Sandbox Code Playgroud)
这意味着,重载分辨率在编译器看到该部件之前执行=delete
- 因此导致错误,因为发现所选的重载被删除.
希望有所帮助.
Mar*_*cia 23
当你=delete
是一个函数时,你实际上是在删除它的定义.
8.4.3删除的定义[dcl.fct.def.delete]
1表单的函数定义:
attribute-specifier-seqopt decl-specifier-seqopt declarator = delete;
被称为已删除的定义.具有已删除定义的函数也称为已删除函数.
但通过这样做,你也宣布了这个功能.引用标准[1]:
4删除的函数是隐式内联的.[注意:单定义规则(3.2)适用于已删除的定义.-end note] 删除函数的定义应该是函数的第一个声明 [...]
所以做a = A()
时,编译器实际上解析到A::operator=(A&&)
,因为它已申报(不A::operator(const A&)
,因为A&&
"更结合",以r值).但是,如果删除其定义,则该行格式不正确.
2除了声明它之外,隐式或显式引用已删除函数的程序是不正确的.
[1]这里强调句子的语气实际上是必要的.标准指示声明函数=delete
d必须首先出现在其它声明之前.但是,它仍然支持删除函数也声明函数的事实.
归档时间: |
|
查看次数: |
5310 次 |
最近记录: |