C++ 移动构造一个C++;11从可调用参数创建的线程对象参数执行线程

C++ 移动构造一个C++;11从可调用参数创建的线程对象参数执行线程,c++,multithreading,c++11,C++,Multithreading,C++11,在C++11初始化列表中,我试图从在别处创建并传递给构造函数的thread对象中移动构造线程。我还尝试使用传入的可调用参数创建thread对象。我一点运气都没有 希望以下(无效)代码将指示我正在尝试执行的操作: “a.cpp” #包括 #包括 阶级事务{ int i; }; 类Impl{ 班级报名{ 事物; 标准:螺纹; 公众: 模板 条目(对象和对象、F和func) :东西 ,线程(func){ } }; 类图{ 地图; 公众: 模板 无效添加(对象和对象、F和func){ map.empla

在C++11初始化列表中,我试图从在别处创建并传递给构造函数的thread对象中移动构造线程。我还尝试使用传入的可调用参数创建thread对象。我一点运气都没有

希望以下(无效)代码将指示我正在尝试执行的操作:

a.cpp

#包括
#包括
阶级事务{
int i;
};
类Impl{
班级报名{
事物;
标准:螺纹;
公众:
模板
条目(对象和对象、F和func)
:东西
,线程(func){
}
};
类图{
地图;
公众:
模板
无效添加(对象和对象、F和func){
map.emplace({thing,{thing,func}});
}
};
事物地图;
void execute(){
}
公众:
无效激活(对象和对象){
添加(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
$ 
$g++-std=c++11-c a.cpp
a、 cpp:在“void Impl::ThingMap::add(Thing&,F&&)[with F=Impl::activate(Thing&)]::\uu lambda0]的实例化中:
a、 cpp:38:45:从这里开始需要
a、 cpp:27:13:错误:调用“std::map::emplace()”时没有匹配的函数
map.emplace({thing,{thing,func}});
^
a、 cpp:27:13:注:候选人为:
在/usr/include/c++/4.8.2/map:61:0中包含的文件中,
来自a.cpp:1:
/usr/include/c++/4.8.2/bits/stl_-map.h:540:2:注意:std::pair std::map::emplace(_-Args&&…[with _-Args={};_-Key=Thing;_-Tp=Impl::Entry;_-Compare=std::less;_-Alloc=std::分配器;typename std:_-Rb_-tree::iterator=std:_-Rb-tree迭代器]
安放(_参数&&…_参数)
^
/usr/include/c++/4.8.2/bits/stl_-map.h:540:2:注意:候选者需要0个参数,提供1个参数
$ 

任何关于如何修复代码的建议都将不胜感激。但是,请不要使用该结构,它的存在是有原因的。

std::map::emplace
是一个模板函数,它接受任意对象来构造键/值对。不能使用列表初始化,因为编译器将无法推断类型

改为指定类型:

template<class F>
void add(Thing& thing, F&& func) {
     map.emplace(thing, Entry{thing, std::forward<F>(func)});
}
模板
无效添加(对象和对象、F和func){
map.emplace(thing,Entry{thing,std::forward(func)});
}

正如gcc指出的,您在这里使用的是初始值设定项列表。或者至少它是这样解释的

map.emplace({thing, {thing, func}});
要修复它,只需在此处显式使用类型:

map.emplace(std::make_pair(thing, Entry(thing, std::thread(std::forward<F>(func)))));
map.emplace(std::make_pair(thing,Entry(thing,std::thread)(std::forward(func ')));

顺便说一句,请注意添加的转发功能。它允许您将函数类型完美地转发到线程

注意:代码仍然缺少一个关于如何在该更改后比较
对象的
std::map
信息。Afaik线程只有来自函数的显式构造函数,这行吗?@bartop Yes:
std::thread
构造(显式地)发生在
条目
中。要创建
事物
std::map
,必须提供一个比较运算符。作为
bool运算符
map.emplace(std::make_pair(thing, Entry(thing, std::thread(std::forward<F>(func)))));