Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在;“移动”;对象有一个;“不平凡”;工会会员?_C++_C++14_Move_Unions - Fatal编程技术网

C++ 为什么在;“移动”;对象有一个;“不平凡”;工会会员?

C++ 为什么在;“移动”;对象有一个;“不平凡”;工会会员?,c++,c++14,move,unions,C++,C++14,Move,Unions,我注意到move可以应用于不与“非平凡”(不确切知道,但如基本类型很好)成员具有联合的对象。例如,编译以下代码(C++14,铿锵): #包括 #包括 福班{ 公众: 联合{ int i; 布尔b; }; Foo(){}; ~Foo(){}; //将构造函数移动到默认值。 Foo(Foo&&)=默认值; //已删除复制构造函数。 Foo(const Foo&)=删除; }; int main(){ std::向量v; v、 向后推(Foo()); } 请注意,复制构造函数已被删除。由于std::

我注意到
move
可以应用于与“非平凡”(不确切知道,但如基本类型很好)成员具有联合的对象。例如,编译以下代码(C++14,铿锵):

#包括
#包括
福班{
公众:
联合{
int i;
布尔b;
};
Foo(){};
~Foo(){};
//将构造函数移动到默认值。
Foo(Foo&&)=默认值;
//已删除复制构造函数。
Foo(const Foo&)=删除;
};
int main(){
std::向量v;
v、 向后推(Foo());
}
请注意,复制构造函数已被删除。由于
std::vector
push_back
可以接受右值引用,因此在这种情况下,它将使用右值引用,并且不会发生
复制。但是,一旦将“非平凡”类型添加到联合中,复制构造函数将被强制执行-因此它将不会编译:

#包括
#包括
福班{
公众:
联合{
int i;
布尔b;
std::string s;//\u M\u impl,this->\u M\u impl.\u M\u finish,
^
/usr/bin/./lib/gcc/x86_64-linux-gnu/7.2.0/../../../../../../../../include/c++/7.2.0/bits/stl_vector.h:954:9:注意:在函数模板的实例化中
此处请求专门化“std::vector::emplace_back”
{emplace_back(std::move(__x));}
^
experiment/miniso.cpp:24:5:注意:在成员函数“std::vector::push_back”的实例化中,此处请求
v、 向后推(Foo());
^
experiment/miniso.cpp:19:3:注意:“Foo”已在此处明确标记为已删除
Foo(const Foo&)=删除;
^
我知道一些关于什么可以移动,什么不能移动的规则,但是这似乎并不容易处理。为什么会发生这种情况,如何解决这一问题,使其不调用复制构造函数


目标编译器是Clang C++14。

它试图调用你的复制构造函数,因为你的移动构造函数已被删除。哦,当然,我知道你编写了
=default
。但是由于联合包含一个具有非平凡移动/复制构造函数的类型,如果不是用户提供的,联合的复制/移动构造函数将被隐式删除

并且,
=默认值
不会使其成为“用户提供的”

换句话说,如果
union
的任何成员需要复制/移动除
memcpy
以外的代码,编译器就不能给它一个复制/移动构造函数(又称为不可复制)。因此,包含联合的类型也不能有编译器生成的复制/移动代码。在这些情况下,必须由您决定如何复制/移动对象


这样的复制/移动构造函数需要知道它是哪种类型。

它试图调用你的复制构造函数,因为你的移动构造函数被删除了。哦,当然,我知道你写了
=default
。但是由于联合包含一个具有非平凡的移动/复制构造函数的类型,如果它不是用户提供的

并且,
=默认值
不会使其成为“用户提供的”

换句话说,如果
union
的任何成员需要复制/移动除
memcpy
以外的代码,编译器就不能给它一个复制/移动构造函数(又称为不可复制)。因此,包含联合的类型也不能有编译器生成的复制/移动代码。在这些情况下,必须由您决定如何复制/移动对象


这样的复制/移动构造函数需要知道它是哪种类型。

我希望联合体中的
std::string
只是一个例子,您如何确定该联合体的某个任意实例(来自某个未指定的源)包含可移动的构造的
std::string
,或其他基本类型之一?如果给定的联合实际上包含
bool
值,尝试移动其据称包含的
std::string
将导致无休止的欢笑。如果您仔细考虑一下,您应该能够回答自己的问题例如,我希望联合体中的
std::string
,您如何确定该联合体的某个任意实例(来自某个未指定的源)包含可移动的构造的
std::string
,或其他基本类型之一?如果给定的联合实际上包含
bool
值,尝试移动其据称包含的
std::string
将导致无休止的欢笑。如果您仔细考虑一下,您应该能够回答自己的问题在…上