为什么使用`无常量副本构造函数时,编译器会抱怨?

问题描述 投票:1回答:1

作为主题,下面的代码是正确的。

#include<iostream>

class ABC     
{  public:  
    ABC() 
    {
        std::cout<< "default construction" << std::endl;
    }

    ABC(ABC& a) 
    {
        std::cout << "copy construction" << std::endl;
    } 

};                         

int main()   
{  
   ABC c1 = ABC(); 
}

无法成功编译:

<source>: In function 'int main()': 
<source>:25:13: error: cannot bind non-const lvalue reference of type 'ABC&' to an rvalue of type 'ABC'
   25 |    ABC c1 = ABC();
      |             ^~~~~
<source>:10:14: note:   initializing argument 1 of 'ABC::ABC(ABC&)'
   10 |     ABC(ABC& a)
      |         ~~~~~^

但是,如果将ABC(ABC& a)替换为ABC(const ABC&),它可以编译。我知道它与关键字const有一定关系。但是我不知道为什么。

您可以在https://godbolt.org/z/jNL5Bd上进行检查。我是C ++的新手。对于此问题,我将不胜感激。

作为主题,下面的代码是正确的。 #include class ABC {public:ABC(){std :: cout <

正如错误消息所言,临时ABC()不能绑定到非常量的左值引用,复制构造函数ABC&不能用于初始化。 (临时可以绑定到左值引用到const或右值引用。)


PS:由于C ++ 17,所以代码可以编译(这并不意味着采用对非const左值引用的复制构造函数是一种好方法),因为可以保证copy elision,所以可以完全消除复制构造。

(重点是我的)

在以下情况下,要求编译器省略类对象的复制和移动构造,即使复制/移动构造函数和析构函数具有明显的副作用

。这些对象直接构造到存储中,否则会将它们复制/移动到其中。 复制/移动构造函数不必存在或不可访问
c++ c++11 constructor copy-constructor move-semantics
1个回答
1
投票

正如错误消息所言,临时ABC()不能绑定到非常量的左值引用,复制构造函数ABC&不能用于初始化。 (临时可以绑定到左值引用到const或右值引用。)

© www.soinside.com 2019 - 2024. All rights reserved.