【问题标题】:Using Bind to produce a parameterless function results in error使用 Bind 生成无参数函数会导致错误
【发布时间】:2011-12-20 09:51:47
【问题描述】:

我试图找出 std::bind 与 boost::signal2 信号的正确用法。

我使用 clang++(来自 Xcode 4.2.1)得到的错误集是:

~/Projects/Myron/Myron/main.cpp:29:59: error: reference to '_1' is ambiguous [3]
     main.resize.connect(std::bind(resize, std::ref(main), _1, _2));
                                                           ^
/Developer/usr/bin/../lib/c++/v1/functional:1496:18: note: candidate found by name lookup is 'std::__1::placeholders::_1' [3]
 extern __ph<1>   _1;
                  ^
/Developer/SDKs/MacOSX10.7.sdk/usr/local/include/boost/bind/placeholders.hpp:55:15: note: candidate found by name lookup is '<anonymous namespace>::_1' [3]
 boost::arg<1> _1;
               ^
~/Projects/Myron/Myron/main.cpp:30:24:{30:24-30:33}: error: no matching function for call to 'bind' [3]
     main.close.connect(std::bind(close, std::ref(main)));
                        ^~~~~~~~~
/Developer/usr/bin/../lib/c++/v1/functional:1789:1: note: candidate template ignored: couldn't infer template argument '_F' [3]
 bind(_F&& __f, _BoundArgs&&... __bound_args)
 ^
/Developer/usr/bin/../lib/c++/v1/functional:1798:1: note: candidate template ignored: couldn't infer template argument '_R' [3]
 bind(_F&& __f, _BoundArgs&&... __bound_args)
 ^
2 errors generated.

它们主要集中在两条线上:

main.resize.connect(std::bind(resize, std::ref(main), _1, _2));
main.close.connect(std::bind(close, std::ref(main)));

其中使用了函数原型:

bool resize(Myron::Window &win, int &width, int &height);
bool close(Myron::Window &win);

并且main是一个Myron::Window&,resize和close分别是:

bs2::signal<bool(int&,int&)> resize;
bs2::signal<bool(void)> close;

我所阅读的和被告知的所有内容都让我相信我在使用这些方面是相当正确的,所以我不确定问题出在哪里。

我意识到第一个错误是 boost::bind 可能通过 Myron.h 文件中的 boost/signals2.hpp 进入这里的问题。第二个错误更加神秘。

完整的主要源文件在这里:

#include <iostream>
#include <functional>
#include <string>
#include <type_traits>

#include "Myron.h"

bool setup();
bool resize(Myron::Window &win, int &width, int &height);
bool close(Myron::Window &win);


bool setup()
{
    using namespace std::placeholders;

    std::cout << "setup()" << std::endl;
    Myron::Window &main = Myron::createWindow(640, 480);

    main.resize.connect(std::bind(resize, std::ref(main), _1, _2));
    main.close.connect(std::bind(close, std::ref(main)));
    return true;
}

bool close(Myron::Window &win)
{
    std::cout << "Window Closed" << std::endl;
    return true;
}

bool resize(Myron::Window &win, int &width, int &height)
{
    std::cout << "Resize: " << width << ", " << height << std::endl;
    return true;
}



int main(int argc, char**argv)
{
    std::cout << "Initialize..." << std::endl;

    Myron::Init(setup);

    std::cout << "Done Initialize." << std::endl;
}

显示所有内容的主要源代码存储库在这里:https://github.com/iaefai/Myron/tree/master/Myron

任何尝试的建议将不胜感激。我曾尝试制作较小的测试用例,但未能成功解决问题。

【问题讨论】:

    标签: c++ c++11 signals clang overload-resolution


    【解决方案1】:

    第二个问题可能是由于过载歧义引起的。具体来说,我怀疑罪魁祸首是系统调用close(),它通过&lt;iostream&gt; 潜入你的范围。尝试将您的回调包含在命名空间中,看看是否有帮助。令我惊讶的是,clang++ 在这种情况下并没有更多帮助,它显示了导致歧义的重载,它通常因其非常清晰的诊断而受到称赞。

    【讨论】:

    • 我把名字改成接近 Close 并且确实解决了这个问题。
    • 我认为现在我将不得不摆脱对信号2的使用,而只使用 std::function 分配。它不是那么好,但是对于这些库来说,boost 并不是最容易为我工作的。
    猜你喜欢
    • 1970-01-01
    • 2019-08-06
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    • 2019-05-31
    • 2013-05-31
    • 1970-01-01
    相关资源
    最近更新 更多