在 C++11 初始化列表中,我正在尝试从其他地方创建并传递给构造函数的线程对象移动构造线程。我还尝试使用传入的可调用参数创建线程对象。我没有任何运气。
希望以下(无效(代码将指示我正在尝试执行的操作:
">阿.cpp">
#include <map>
#include <thread>
class Thing {
int i;
};
class Impl {
class Entry {
Thing thing;
std::thread thread;
public:
template<class F>
Entry(Thing& thing, F&& func)
: thing(thing)
, thread(func) {
}
};
class ThingMap {
std::map<Thing, Entry> map;
public:
template<class F>
void add(Thing& thing, F&& func) {
map.emplace({thing, {thing, func}});
}
};
ThingMap things;
void execute() {
}
public:
void activate(Thing& thing) {
things.add(thing, [this]{execute();});
}
};
以下是我的 g++ 4.8.5 编译器的错误:
$ g++ -std=c++11 -c a.cpp
a.cpp: In instantiation of ‘void Impl::ThingMap::add(Thing&, F&&) [with F = Impl::activate(Thing&)::__lambda0]’:
a.cpp:38:45: required from here
a.cpp:27:13: error: no matching function for call to ‘std::map<Thing, Impl::Entry>::emplace(<brace-enclosed initializer list>)’
map.emplace({thing, {thing, func}});
^
a.cpp:27:13: note: candidate is:
In file included from /usr/include/c++/4.8.2/map:61:0,
from a.cpp:1:
/usr/include/c++/4.8.2/bits/stl_map.h:540:2: note: std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::emplace(_Args&& ...) [with _Args = {}; _Key = Thing; _Tp = Impl::Entry; _Compare = std::less<Thing>; _Alloc = std::allocator<std::pair<const Thing, Impl::Entry> >; typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator = std::_Rb_tree_iterator<std::pair<const Thing, Impl::Entry> >]
emplace(_Args&&... __args)
^
/usr/include/c++/4.8.2/bits/stl_map.h:540:2: note: candidate expects 0 arguments, 1 provided
$
关于如何修复代码的任何和所有建议将不胜感激。请不要管这个结构,但是,它的存在是有原因的。
std::map::emplace
是一个模板函数,接受任意对象来构造键/值对。不能使用列表初始化,因为编译器将无法推断类型。
请改为指定类型:
template<class F>
void add(Thing& thing, F&& func) {
map.emplace(thing, Entry{thing, std::forward<F>(func)});
}
正如 gcc 指出的那样,您在这里使用的是初始值设定项列表。或者至少它是这样解释的。
map.emplace({thing, {thing, func}});
要修复它,只需在此处显式使用类型:
map.emplace(std::make_pair(thing, Entry(thing, std::thread(std::forward<F>(func)))));
顺便说一句,请注意添加的转发功能。它允许您完美地将函数类型转发到线程