Class 删除了拷贝构造函数还能拷贝吗?
Class with a deleted copy constructor can be still copied?
我有一个简单的功能:
void foo(atomic<int> a) { }
碰巧我可以这样调用foo()
:
foo({ });
但我不能这样做:
foo(atomic<int>{ });
由于错误消息 copy constructor is a deleted function
。我已经用 C++14 编译了。
- 第一种方式调用什么构造函数:创建构造函数还是移动构造函数?
- 为什么第二种方式不调用移动构造函数?
foo()
的这两个调用在 C++17 中编译良好 - 为什么?
在foo({ });
中,参数为copy list-initialized。结果它由 std::atomic
.
的默认构造函数初始化
在foo(atomic<int>{ });
中,参数为copy-initialized from the temporary std::atomic
(i.e. atomic<int>{ }
). Before C++17 even the copy/move operation might be elided the copy/move constructor still has to be present and accessible. Since C++17 this is not required again because of mandatory copy elision,保证参数直接由std::atomic
的默认构造函数初始化。
First, if T is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object: see copy elision (since C++17)
Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible: (since C++17)
我有一个简单的功能:
void foo(atomic<int> a) { }
碰巧我可以这样调用foo()
:
foo({ });
但我不能这样做:
foo(atomic<int>{ });
由于错误消息 copy constructor is a deleted function
。我已经用 C++14 编译了。
- 第一种方式调用什么构造函数:创建构造函数还是移动构造函数?
- 为什么第二种方式不调用移动构造函数?
foo()
的这两个调用在 C++17 中编译良好 - 为什么?
在foo({ });
中,参数为copy list-initialized。结果它由 std::atomic
.
在foo(atomic<int>{ });
中,参数为copy-initialized from the temporary std::atomic
(i.e. atomic<int>{ }
). Before C++17 even the copy/move operation might be elided the copy/move constructor still has to be present and accessible. Since C++17 this is not required again because of mandatory copy elision,保证参数直接由std::atomic
的默认构造函数初始化。
First, if T is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object: see copy elision (since C++17)
Under the following circumstances, the compilers are required to omit the copy and move construction of class objects, even if the copy/move constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied/moved to. The copy/move constructors need not be present or accessible: (since C++17)