【问题标题】:Using boost move with an instance parameter使用带有实例参数的 boost move
【发布时间】:2017-12-31 12:27:41
【问题描述】:

我有一个函数处理一个只能移动的实例,它是其他东西的包装器。该对象提供了访问包装对象的方法和一些要求它不可复制的检查。 (用例是一个值表,其中包装器的 dtor 应该断言所有值都已被访问)

我从包装类型定义了一个自定义 ctor 并实现了移动 ctor/assignment。

但是由于尝试复制而出现错误:error: 'Movable::Movable(Movable&)' is private within this context

它在 C++11 中运行良好,但我需要移植到 C++03。如果没有包装器的显式实例化并将其移动到函数中,我该如何做到这一点?

MWE:

#include <boost/move/move.hpp>
#include <iostream>

class Movable{
    BOOST_MOVABLE_BUT_NOT_COPYABLE(Movable)
public:
    int i;
    Movable(int j):i(j){}
    Movable(BOOST_RV_REF(Movable) other) // Move constructor
        : i(boost::move(other.i))
    {}

    Movable& operator=(BOOST_RV_REF(Movable) other) // Move assignment
    {
        if(this != &other)
            i = boost::move(other.i);
        return *this;
    }
};

void bar(Movable mov){
    mov.i = 22;
    std::cout << mov.i;
}

int main(int argc, char* argv[])
{
    bar(5);
    return 0;
}

【问题讨论】:

  • 据我测试,您可以跳过右值的移动部分并致电bar(Movable(5)); coliru.stacked-crooked.com/a/a4c6bbeb20334fc6
  • 那更好。有机会避免这种情况吗?我的意思是非显式转换运算符/ctor 旨在避免这种噪音。
  • 也许有一些技巧,我没有用 C++03 写过太高级的代码,但对我来说不应该。您已经从我的示例中隐式转换为 boost::rv&lt;Movable&gt;with 签名,编译器无法推断隐式两次(即:5 -&gt; Movable (5) -&gt; boost::rv&lt;Movable&gt;(Movable(5))

标签: c++ c++11 boost move-semantics


【解决方案1】:

问题似乎是隐式转换构造函数干扰了复制构造函数抑制。

任意使用

Movable m(5);
bar(boost::move(m));

或者

bar(Movable(5));

确保选择显式构造函数。显然,这意味着你甚至可以标记它explicit

Live On Coliru

#include <boost/move/move.hpp>
#include <iostream>

class Movable{
    BOOST_MOVABLE_BUT_NOT_COPYABLE(Movable)
public:
    int i;
    explicit Movable(int j):i(j){}
    Movable(BOOST_RV_REF(Movable) other) // Move constructor
        : i(boost::move(other.i))
    {}

    Movable& operator=(BOOST_RV_REF(Movable) other) // Move assignment
    {
        if(this != &other)
            i = boost::move(other.i);
        return *this;
    }
};

void bar(Movable mov){
    std::cout << mov.i << " ";
    mov.i = 22;
    std::cout << mov.i << "\n";
}

int main() {
    Movable m(5);
    bar(boost::move(m));

    bar(Movable(6));
}

打印

5 22
6 22

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多