移动向量元素的分配不起作用,而是调用复制分配
Move Assignment of a Vector Element not working, Copy Assignment is called instead
我有一个 class 不可默认构造、不可复制构造或不可复制分配。它是可移动构造和可移动分配的。
struct SG_MotionState {
frameId_t frameId;
btTransform transform;
vector<sgCustomFieldData_t> mCustomFields;
sgCustomFieldLayout_t & mLayout;
SG_MotionState (sgCustomFieldLayout_t & _mLayout) : mLayout(_mLayout) {}
// Disable copy
private: // No copying allowed!
SG_MotionState& operator = (const SG_MotionState & other);
SG_MotionState(const SG_MotionState & other);
public: // Only moving
inline SG_MotionState(SG_MotionState&& other) noexcept = default;
inline SG_MotionState& operator = (SG_MotionState&& other) noexcept = default;
... // Impl
}
我将此 class 的实例存储在 std::vector:
data.push_back(std::move(t));
稍后我想替换数组中的值,丢弃原始值。但是当我尝试时:
data[position] = std::move(t);
编译器 (g++ 10.2) 尝试调用复制分配
SG_MotionState& operator = (const SG_MotionState & other)
而不是调用移动分配
SG_MotionState& operator = (SG_MotionState&& other)
。我如何对 std::vector 元素进行移动分配?
容器相关部分class:
template<typename T, uint MAX_SIZE>
class t2_ringbuffer {
public:
/// Stores an item in a container that grows in size
/// until a maxiumum is reached, thereafter it overrides old values
std::vector<T> data;
uint zeroIndex;
t2_ringbuffer() : zeroIndex(0) {}
void push_back(T && t) { // Move semantics version
if (data.size() < MAX_SIZE)
data.push_back(std::move(t));
else {
data[zeroIndex] = std::move(t);
zeroIndex++;
if (zeroIndex >= MAX_SIZE)
zeroIndex = 0;
}
}
... // more impl
}
编辑:
这是准确的错误消息:
temp/rsserver/dataStructures/ringbuffer.hpp: In instantiation of ‘void t2_ringbuffer<T, MAX_SIZE>::push_back(T&&) [with T = SG_MotionState; unsigned int MAX_SIZE = 60]’:
temp/rsserver/sgNode.cpp:550:40: required from here
temp/rsserver/dataStructures/ringbuffer.hpp:30:20: error: ‘SG_MotionState& SG_MotionState::operator=(const SG_MotionState&)’ is private within this context
30 | data[zeroIndex] = std::move(t);
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
编辑 2:class 的属性:
is_constructible: false
is_trivially_constructible: false
is_copy_constructible: false
is_nothrow_copy_constructible: false
is_move_constructible: true
is_nothrow_move_constructible: true
编辑 3:最小示例:
https://godbolt.org/z/WWorP1
您的问题在于缺少移动赋值运算符。
看你的class,你默认了这个操作
不幸的是,= default
意味着您获得默认行为,而不是创建此方法。这真是令人困惑。
为了更容易发现这一点,我最近在我正在处理的代码库中启用了以下 clang 警告作为错误:https://clang.llvm.org/docs/DiagnosticsReference.html#wdefaulted-function-deleted
(也许 GCC 有类似的东西)
长话短说,如果您的基础 class 或成员不允许此操作,则您的 class 不能默认此操作。
在这种情况下,您有一个引用作为成员,因为不能重新分配引用,也不能提供赋值运算符。
可能的解决方法是:存储为原始指针,或存储为 std:: reference_wrapper
。
PS:请将您删除的方法 public 并使用 = delete
,它会给出更好的错误消息
我有一个 class 不可默认构造、不可复制构造或不可复制分配。它是可移动构造和可移动分配的。
struct SG_MotionState {
frameId_t frameId;
btTransform transform;
vector<sgCustomFieldData_t> mCustomFields;
sgCustomFieldLayout_t & mLayout;
SG_MotionState (sgCustomFieldLayout_t & _mLayout) : mLayout(_mLayout) {}
// Disable copy
private: // No copying allowed!
SG_MotionState& operator = (const SG_MotionState & other);
SG_MotionState(const SG_MotionState & other);
public: // Only moving
inline SG_MotionState(SG_MotionState&& other) noexcept = default;
inline SG_MotionState& operator = (SG_MotionState&& other) noexcept = default;
... // Impl
}
我将此 class 的实例存储在 std::vector:
data.push_back(std::move(t));
稍后我想替换数组中的值,丢弃原始值。但是当我尝试时:
data[position] = std::move(t);
编译器 (g++ 10.2) 尝试调用复制分配
SG_MotionState& operator = (const SG_MotionState & other)
而不是调用移动分配
SG_MotionState& operator = (SG_MotionState&& other)
。我如何对 std::vector 元素进行移动分配?
容器相关部分class:
template<typename T, uint MAX_SIZE>
class t2_ringbuffer {
public:
/// Stores an item in a container that grows in size
/// until a maxiumum is reached, thereafter it overrides old values
std::vector<T> data;
uint zeroIndex;
t2_ringbuffer() : zeroIndex(0) {}
void push_back(T && t) { // Move semantics version
if (data.size() < MAX_SIZE)
data.push_back(std::move(t));
else {
data[zeroIndex] = std::move(t);
zeroIndex++;
if (zeroIndex >= MAX_SIZE)
zeroIndex = 0;
}
}
... // more impl
}
编辑: 这是准确的错误消息:
temp/rsserver/dataStructures/ringbuffer.hpp: In instantiation of ‘void t2_ringbuffer<T, MAX_SIZE>::push_back(T&&) [with T = SG_MotionState; unsigned int MAX_SIZE = 60]’:
temp/rsserver/sgNode.cpp:550:40: required from here
temp/rsserver/dataStructures/ringbuffer.hpp:30:20: error: ‘SG_MotionState& SG_MotionState::operator=(const SG_MotionState&)’ is private within this context
30 | data[zeroIndex] = std::move(t);
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
编辑 2:class 的属性:
is_constructible: false
is_trivially_constructible: false
is_copy_constructible: false
is_nothrow_copy_constructible: false
is_move_constructible: true
is_nothrow_move_constructible: true
编辑 3:最小示例: https://godbolt.org/z/WWorP1
您的问题在于缺少移动赋值运算符。 看你的class,你默认了这个操作
不幸的是,= default
意味着您获得默认行为,而不是创建此方法。这真是令人困惑。
为了更容易发现这一点,我最近在我正在处理的代码库中启用了以下 clang 警告作为错误:https://clang.llvm.org/docs/DiagnosticsReference.html#wdefaulted-function-deleted (也许 GCC 有类似的东西)
长话短说,如果您的基础 class 或成员不允许此操作,则您的 class 不能默认此操作。
在这种情况下,您有一个引用作为成员,因为不能重新分配引用,也不能提供赋值运算符。
可能的解决方法是:存储为原始指针,或存储为 std:: reference_wrapper
。
PS:请将您删除的方法 public 并使用 = delete
,它会给出更好的错误消息