Boost :: thread:lambda捕获中的语法混淆

时间:2014-01-16 00:23:49

标签: c++ boost c++11 lambda

我已将boost::thread.hpp包含在我的某些头文件中,并且我在class结构之一中使用了此代码:

#include <boost/thread.hpp>
#include <functional>

typedef std::function<void ()> XEvent;

enum X_Widget_Type
{
    XW_BUTTON,
    XW_TEXTBOX,
    XW_CHECK_BOX,
    XW_COMBO_BOX
};
//XWidget.h
class XWidget
{
public:
    XWidget(const char *name, const Rect& rect, X_Widget_Type type, const HWND parent) :

     onClick(nullptr)
    ,id(++X_ID_COUNTER)
    {
        int flags = WS_CHILD | WS_VISIBLE | WS_TABSTOP;
        char widget_name[128];

        switch (type)
        {
        case XW_BUTTON:
            flags |= BS_DEFPUSHBUTTON;
            strcpy(widget_name, "BUTTON");
            break;
        case XW_TEXTBOX:
            flags |= ES_USER_PRESENT;
            strcpy(widget_name, "EDIT");
            break;
        case XW_CHECK_BOX:
            flags |= BS_AUTOCHECKBOX;
            strcpy(widget_name, "BUTTON");
            break;
        case XW_COMBO_BOX:
            flags |= CBS_DROPDOWN;
            strcpy(widget_name, "COMBOBOX");
        }

        handle = CreateWindowEx(
            WS_EX_STATICEDGE,
            widget_name, name,
            flags,
            rect.x, rect.y,
            rect.width, rect.height,
            parent, (HMENU)getID(),
            GetModuleHandle(NULL),
            NULL);
    }

    XEvent onClick;

private:
    int XWidget::X_ID_COUNTER;
}

//XCheckbox.h
class XCheckbox :
    public XWidget
{
    XCheckbox(const char *name, const Rect& rect, const HWND parent) :
        XWidget(name, rect, XW_CHECK_BOX, parent) { }
    ...
}

//main.cpp

bool cheat1 = false;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

    CWin app("win32app", nCmdShow);
    ...

    XCheckbox chkbox("checkbox", {0, 0, 50, 22}, app.getHandle());

    XCheckbox.onClick =
    [chkbox, app, &cheat1] //  <--this doesn't compile when I include `boost::thread.hpp` ?
    {
        ...
    };

    ...
}

现在,当我包含boost::thread.hpp时,它不会编译,我收到了一堆错误和警告:

||=== Build: Debug in rasman (compiler: GNU GCC Compiler) ===|
D:\CPP\rasman\src\main.cpp||In function 'int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)':|
D:\CPP\rasman\src\main.cpp|85|warning: capture of variable 'cheat1' with non-automatic storage duration [enabled by default]|
D:\CPP\rasman\src\main.cpp|43|note: 'bool cheat1' declared here|
D:\CPP\rasman\src\main.cpp|108|warning: comparison between signed and unsigned integer expressions [-Wsign-compare]|
d:\cb\codeblocks\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_construct.h||In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = boost::thread; _Args = {const boost::thread&}]':|
d:\cb\codeblocks\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_uninitialized.h|75|required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const boost::thread*, std::vector<boost::thread> >; _ForwardIterator = boost::thread*; bool _TrivialValueTypes = false]'|
d:\cb\codeblocks\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_uninitialized.h|117|required from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const boost::thread*, std::vector<boost::thread> >; _ForwardIterator = boost::thread*]'|
d:\cb\codeblocks\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_uninitialized.h|258|required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<const boost::thread*, std::vector<boost::thread> >; _ForwardIterator = boost::thread*; _Tp = boost::thread]'|
d:\cb\codeblocks\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_vector.h|316|required from 'std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = boost::thread; _Alloc = std::allocator<boost::thread>]'|
include\cwin.h|25|required from here|
d:\cb\codeblocks\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\stl_construct.h|75|error: use of deleted function 'boost::thread::thread(const boost::thread&)'|
D:\cb\boost_1_55_0\boost\thread\detail\thread.hpp|165|error: declared here|
D:\cb\boost_1_55_0\boost\thread\detail\delete.hpp|20|note: in definition of macro 'BOOST_THREAD_DELETE_COPY_CTOR'|
D:\cb\boost_1_55_0\boost\thread\detail\move.hpp|231|note: in expansion of macro 'BOOST_THREAD_NO_COPYABLE'|
D:\cb\boost_1_55_0\boost\thread\detail\thread.hpp|165|note: in expansion of macro 'BOOST_THREAD_MOVABLE_ONLY'|
D:\cb\boost_1_55_0\boost\system\error_code.hpp|222|warning: 'boost::system::posix_category' defined but not used [-Wunused-variable]|
D:\cb\boost_1_55_0\boost\system\error_code.hpp|223|warning: 'boost::system::errno_ecat' defined but not used [-Wunused-variable]|
D:\cb\boost_1_55_0\boost\system\error_code.hpp|224|warning: 'boost::system::native_ecat' defined but not used [-Wunused-variable]|
||=== Build failed: 2 error(s), 11 warning(s) (0 minute(s), 9 second(s)) ===|

但是如果我排除了boost::thread.hpp,它编译得很好吗?

我在这里失踪了什么?有什么问题?

更新

我想要包含boost::thread.hpp的原因是因为这个功能

void createThread(std::function<void ()> thread_function)
{
    threads.push_back(boost::thread(thread_function));
}

template<typename T>
void createThread(T thread_function)
{
    threads.push_back(boost::thread(thread_function));
}

1 个答案:

答案 0 :(得分:1)

忽略您遇到的奇怪boost::thread错误,问题在于尝试将对静态变量的引用传递给lambda函数,这是不可能的(有关原因的详细信息,请参阅此问题:{ {3}})。

t的长短是你不需要将cheat1传递给lambda函数beacuse cheat1已经可以访问。删除lambda的&cheat1参数并正常访问该变量。