gpt4 book ai didi

c++ - 移动语义+对成员成员变量的引用-解决方案和命名法?

转载 作者:搜寻专家 更新时间:2023-10-31 02:05:30 25 4
gpt4 key购买 nike

我遇到过几次的基本问题是 C 类有 A 类和 B 类类型的成员,而 B 的构造函数引用了 A。当你尝试 std::move C 时,新的B 获得对旧 A 的引用,旧 A 已因移动而失效。

所以我的问题是:这个有名字吗?我一直在谷歌上搜索解决方案,但找不到合适的搜索词。

过去,我的解决方案是“不要那样做”:让 B 拥有 A,让 C 从 B 那里获得 A。但我现在遇到了这样的情况,这是行不通的。相反,我必须在移动后修复引用。

我正在考虑通过编写 reference_wrapper 的替代品来强制实现,该 reference_wrapper 会因移动操作而失效。但在我 promise 之前,我想知道是否有现有的解决方案(例如 boost 某些东西)。

这是一些代码:

#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;
}

最佳答案

不知道此模式的名称,但您不必定义引用包装器的替代品。只需将移动构造函数添加到 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 的移动构造函数。只需对 struct C 进行此更改就足以满足您的需求。我已经更新了指向 cpp.sh 的链接。指向新的解决方案。

关于c++ - 移动语义+对成员成员变量的引用-解决方案和命名法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51878714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com