我碰到过几次基本问题是,类C具有类A和类B的成员,而类B的构造函数引用了A。当您尝试std :: move C时,新的B获得了对旧A的引用,此举已被此举无效。
所以我的问题是:有这个名字吗?我一直在寻找解决方案,但找不到正确的搜索词。
过去,我的解决方案是“不要那样做”:让B拥有A,让C从B获得A。但是现在我遇到了无法解决的情况。相反,我必须在移动后修复引用。
我正在考虑通过编写对reference_wrapper的替换(通过移动操作使其无效)来强制执行此操作。但是在我做出承诺之前,我想知道是否存在现有的解决方案(例如,增强某些功能)。
以下是一些代码:
#include <iostream>
#include <functional>
struct A
{
A( int x )
: m_x( x )
, m_ok( true )
{
}
A( const A& ) = delete;
A& operator=( const A& ) = delete;
A( A&& other )
: m_x( std::move( other.m_x ) )
, m_ok( true )
{
other.m_ok = false;
}
A& operator=( A&& other )
{
m_x = std::move( other.m_x );
m_ok = true;
other.m_ok = false;
return *this;
}
int m_x;
bool m_ok;
};
struct B
{
B( A& a )
: m_a( a )
{
}
std::reference_wrapper<A> m_a;
};
struct C
{
C( int x )
: m_a( x )
, m_b( m_a )
{
}
A m_a;
B m_b;
};
int main()
{
C oldc( 1 );
C newc( std::move( oldc ) );
std::cout << "C.A: " << newc.m_a.m_ok << " C.B.A: " << newc.m_b.m_a.get().m_ok << std::endl;
return 0;
}
答案 0 :(得分:2)
不知道此模式的名称,但是您不必为参考包装器定义一个替换。只需将move构造函数添加到struct C
struct C {
C( int x )
: m_a( x )
, m_b( m_a ) { }
C(C&& c) : m_a(std::move(c.m_a)), m_b(m_a) { }
A m_a;
B m_b;
};
请参见http://cpp.sh/374ca 输出为C.A:1 C.B.A:1
编辑:我刚刚意识到,甚至不需要B的移动ctor。只需对struct C
进行此更改,就足以完成您要执行的操作。我已经更新了指向cpp.sh的链接。指向新的解决方案。