【发布时间】:2017-11-28 21:21:46
【问题描述】:
我正在尝试设置一个模板来交换数组,以便在许多类的移动构造函数中使用:
template <class T> void tools_swap_array(T* & a, T* & b) noexcept
{
auto tmp(a);
a = b;
b = tmp;
}
现在我想在移动构造函数中使用它,并通过一个名为 move_from() 的通用方法移动赋值运算符:
void label::move_from(label && ref) noexcept
{
tools_swap_array((char *)val, (char*)ref.val);
}
其中 val 是类标签的字段:
class label
{
public:
// [...]
label(label && ref) { move_from(std::move(ref)); };
label & operator = (label && ref) { move_from(std::move(ref)); return *this; };
// [...]
private:
char val[LABEL_SIZE];
};
但是当我运行编译器时,它在 move_from() 中失败,告诉 ref.val 是一个右值!
error: invalid initialization of non-const reference of type 'char*&'
from an rvalue of type 'char*'
tools_swap_array((char *)val, (char*)ref.val);
^
我认为“label && ref”将是 move_from() 中的左值,“ref.val”也是如此。那么,我是否仍然误解了 C++11 对右值的引用,或者这是一个编译器错误?
感谢任何提示!
【问题讨论】:
-
使用
(char *)val进行强制转换会生成char*类型的rvalue(临时对象),它指向与val相同的地址。非常量引用不能引用右值。编译器说(char*)ref.val是一个右值,而不是ref.val。 -
除此之外,交换两个指向任意大小数组开头的指针根本不会修改所述数组。
-
在 c++ 中编程时停止使用原始指针。这些是为罕见的例外情况保留的,这些情况很可能已经用 c++ 标准库中的工具解决了。
-
@user0042 使用原始指针本身并没有错。您应该避免的是在所有权的情况下使用原始指针。另请参阅 Cpp 核心指南的 R.3。
-
我了解 std::unique_ptr 和 std::shared_ptr,但这是旧代码 (C++98) 我正在对 C++14 进行一些更新,主要是为了尽可能多地利用move semantics ...但我不会全部重写:)
标签: c++ rvalue-reference