• boost bind 表达式中的是值语义还是指针语义?


    bind 表达式中的是值语义还是指针语义?

    当我们传递某种类型的实例给一个 bind 表达式时,它将被复制,除非我们显式地告诉 bind 不要复制它。要看我们怎么做,这可能是至关重要的。为了看一下在我们背后发生了什么事情,我们创建一个 tracer 类,它可以告诉我们它什么时候被缺省构造、被复制构造、被赋值,以及被析构。这样,我们就可以很容易看到用不同的方式使用 bind 会如何影响我们传送的实例。以下是完整的 tracer 类。

    class tracer {
    public:
    tracer() {
    std::cout << "tracer::tracer()\n";
    }

    tracer(const tracer& other) {
    std::cout << "tracer::tracer(const tracer& other)\n";
    }

    tracer& operator=(const tracer& other) {
    std::cout <<
    "tracer& tracer::operator=(const tracer& other)\n";
    return *this;
    }

    ~tracer() {
    std::cout << "tracer::~tracer()\n";
    }

    void print(const std::string& s) const {
    std::cout << s << '\n';
    }
    };

    我们把我们的 tracer 类用于一个普通的 bind 表达式,象下面这样。

    tracer t;
    boost::bind(&tracer::print,t,_1)
    (std::string("I'm called on a copy of t\n"));

    运行这段代码将产生以下输出,可以清楚地看到有很多拷贝产生。

    tracer::tracer()
    tracer::tracer(const tracer& other)
    tracer::tracer(const tracer& other)
    tracer::tracer(const tracer& other)
    tracer::~tracer()
    tracer::tracer(const tracer& other)
    tracer::~tracer()
    tracer::~tracer()
    I'm called on a copy of t

    tracer::~tracer()
    tracer::~tracer() // 译注:原文没有这一行,有误

    如果我们使用的对象的拷贝动作代价昂贵,我们也许就不能这样用 bind 了。但是,拷贝还是有优点的。它意味着 bind 表达式以及由它所得到的绑定器不依赖于原始对象(在这里是 t)的生存期,这通常正是想要的。要避免复制,我们必须告诉 bind 我们想传递引用而不是它所假定的传值。我们要用 boost::refboost::cref (分别用于引用和 const 引用)来做到这一点,它们也是 Boost.Bind 库的一部分。对我们的 tracer 类使用 boost::ref ,测试代码现在看起来象这样:

    tracer t;
    boost::bind(&tracer::print,boost::ref(t),_1)(
    std::string("I'm called directly on t\n"));

    Executing the code gives us this:

    tracer::tracer()
    I'm called directly on t

    tracer::~tracer() // 译注:原文为 tracer::~tracer,有误

    这正是我们要的,避免了无谓的复制。bind 表达式使用原始的实例,这意味着没有 tracer 对象的拷贝了。当然,它同时也意味着绑定器现在要依赖于 tracer 实例的生存期了。还有一种避免复制的方法;就是通过指针来传递参数而不是通过值来传递。

    tracer t;
    boost::bind(&tracer::print,&t,_1)(
    std::string("I'm called directly on t\n"));

    因此说,bind 总是执行复制。如果你通过值来传递,对象将被复制,这可能对性能有害或者产生不必要的影响。为了避免复制对象,你可以使用 boost::ref/boost::cref 或者使用指针语义。

  • 相关阅读:
    Neko's loop HDU-6444(网络赛1007)
    Parameters
    SETLOCAL
    RD / RMDIR Command
    devenv 命令用法
    Cannot determine the location of the VS Common Tools folder.
    'DEVENV' is not recognized as an internal or external command,
    How to change Visual Studio default environment setting
    error signing assembly unknown error
    What is the Xcopy Command?:
  • 原文地址:https://www.cnblogs.com/ghost240/p/2531282.html
Copyright © 2020-2023  润新知