带有提升的C++ 11占位符

lea*_*vst 15 c++ boost c++11

这段代码......

int main()
{
    using namespace std::placeholders;
    ClassA a;
    ClassB b, b2;
    a.SigA.connect( std::bind(&ClassB::PrintFoo, &b) );
    a.SigB.connect( std::bind(&ClassB::PrintInt, b,  _1));
    a.SigB.connect( std::bind(&ClassB::PrintInt, &b2, _1));

    a.SigA();
    a.SigB(4);
}
Run Code Online (Sandbox Code Playgroud)

给出编译错误,"错误:引用'_1'是不明确的"

它可以通过完全限定占位符来修复...

int main()
{
    // using namespace std::placeholders;
    ClassA a;
    ClassB b, b2;
    a.SigA.connect( std::bind(&ClassB::PrintFoo, &b) );
    a.SigB.connect( std::bind(&ClassB::PrintInt, b,  std::placeholders::_1));
    a.SigB.connect( std::bind(&ClassB::PrintInt, &b2, std::placeholders::_1));

    a.SigA();
    a.SigB(4);
}
Run Code Online (Sandbox Code Playgroud)

...但为什么第一个代码片段不起作用?

编辑

为了防止任何歧义,我正在使用Clang和Boost 1.52进行编译,--stdlib=libc++ -std=c++0x整个代码块就是这个......

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

struct ClassA
{
    boost::signals2::signal<void ()>    SigA;
    boost::signals2::signal<void (int)> SigB;
};

struct ClassB
{
    void PrintFoo()      { std::cout << "Foo" << std::endl; }
    void PrintInt(int i) { std::cout << "Bar: " << i << std::endl; }
};

int main()
{
    // using namespace std::placeholders;
    ClassA a;
    ClassB b, b2;
    a.SigA.connect( std::bind(&ClassB::PrintFoo, &b) );
    a.SigB.connect( std::bind(&ClassB::PrintInt, b,  std::placeholders::_1));
    a.SigB.connect( std::bind(&ClassB::PrintInt, &b2, std::placeholders::_1));

    a.SigA();
    a.SigB(4);
}
Run Code Online (Sandbox Code Playgroud)

Jes*_*ood 47

让我们看看包含的工作原理:

#include <boost/signals2.hpp>包括#include <boost/signals2/signal.hpp> 哪些包括#include <boost/signals2/slot.hpp>哪些包括#include <boost/bind.hpp>哪些包括#include <boost/bind/bind.hpp>哪些包括在全局命名空间中include <boost/bind/placeholders.hpp>使用static boost::arg<1> _1;*,因此含糊不清.

*:从技术上讲,_1它位于一个未命名的命名空间中,但由于using指令而可见.

一种解决方法是在文件顶部定义以下内容,以便<boost/bind/placeholders.hpp>不包括在内:

#define BOOST_BIND_NO_PLACEHOLDERS
Run Code Online (Sandbox Code Playgroud)


Nic*_*las 13

C++看到两个名为的全局标识符_1.它std::placeholders::_1不是你的意思而不是Boost的意思_1.这是标准库将它们放入嵌套命名空间的原因之一:防止像这样的意外冲突.

如果您需要缩短它们,只需创建一个简单的命名空间别名:

namespace ph = std::placeholders
Run Code Online (Sandbox Code Playgroud)

那就是ph::_1.