Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;11个带boost的占位符_C++_C++11_Boost - Fatal编程技术网

C++ C++;11个带boost的占位符

C++ C++;11个带boost的占位符,c++,c++11,boost,C++,C++11,Boost,此代码 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(&

此代码

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);
}
给出编译错误,“错误:对“_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);
}
…但为什么第一个代码段不起作用

编辑

为了避免任何歧义,我正在使用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);
}
#包括
#包括
结构类A
{
升压::信号2::信号SigA;
升压::信号2::信号SigB;
};
结构类B
{

void PrintFoo(){std::coutC++看到两个名为
\u 1
的全局标识符。它不知道您指的是
std::placeholder::\u 1
而不是Boost的
\u 1
。这就是标准库将它们放在嵌套命名空间中的原因之一:防止像这样的意外冲突

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

namespace ph = std::placeholders

然后就是
ph::_1

让我们看看include是如何工作的:

#包括
包括
#包括 其中包括
#include
其中包括
#include
其中包括
#include
其中包括
include
,它在全局名称空间中使用
静态boost::arg\u 1;
*,因此存在歧义

*:从技术上讲,
\u 1
位于未命名的命名空间中,但由于using指令,它可见

一种解决方法是在文件顶部定义以下内容,以便不包括

#define BOOST_BIND_NO_PLACEHOLDERS

GCC提供有关错误的以下信息:

.../include/c++/4.7.0/functional:864:34: \
    error: candidates are: const std::_Placeholder<1> std::placeholders::_1
.../boost/1.49.0/boost/bind/placeholders.hpp:55:15: \
    error:                 boost::arg<1> {anonymous}::_1
../include/c++/4.7.0/functional:864:34:\
错误:候选项为:const std::_占位符std::占位符::_1
…/boost/1.49.0/boost/bind/placeholders.hpp:55:15:\
错误:boost::arg{anonymous}::\u 1
问题的提示可以在第二个错误中找到:
boost::arg{anonymous}::_1

原因是boost占位符位于全局命名空间中的匿名命名空间中

namespace
{
    boost::arg<1> _1;
    // etc...
} // unnamed namespace
名称空间
{
boost::arg_1;
//等等。。。
}//未命名的命名空间
由于boost占位符位于匿名名称空间中,并且您正在将
std::placeholder
导入全局名称空间,因此它们现在都在全局范围内可用

因此,编译器无法知道所引用的符号


如Nicol建议的,使用命名空间别名来创建一个速记前缀,以<代码> STD::占位符::“1”/“代码”以减少键入。

< P>因为您使用的是 STD::BIN < /代码>。我想您有C++ 11的支持。请考虑这个版本(即,喜欢lambdas超过<代码> STD::BIN < /COD>)


通过使用局部变量在范围内解决此问题的另一种解决方法:

{
    auto& _1 = std::placeholders::_1;
    auto f = std::bind(&Foo::bar, b, _1);
    ...
}

你在用什么…编译器?编辑:没关系,
clang
使用
\uuu1
作为它奇怪的名称空间。如果范围中还有其他称为1的东西,那么你会得到这个错误。有点太晚了!很好。Bind很难看!+1在所有伟大的答案中,这一个最直接地回答了这个问题,所以+1/accept我很想知道hy Boost这样污染了全局名称空间?为什么不让用户使用名称空间Boost::占位符;而不管他们想在哪里?
{
    auto& _1 = std::placeholders::_1;
    auto f = std::bind(&Foo::bar, b, _1);
    ...
}