我有一个<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.alert = function($event) {
if ($scope.currentElement) {
alert($scope.currentElement.value);
}
}
$scope.setFocus = function(event) {
$scope.currentElement = event.target;
}
$scope.cancelFocus = function(event) {
$scope.currentElement = false;
}
});
</script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div ng-init="names=['A', 'B', 'C']">
<select class="form-control input-sm" ng-model="fda" ng-change="alert()" ng-focus="setFocus($event)" ng-blur="cancelFocus($event)" ng-options="value for value in names">
</select>
</div>
</body>
</html>
类,其中包含一个Tester
对象和一个std:thread
中的一个std::vector
。我知道我无法复制线程,所以Tester
没问题,但是为什么push_back
无法正常工作?我的代码中的副本在哪里?
emplace_back
答案 0 :(得分:15)
您的代码中有几个小问题
您错过了结尾的分号:
th.join()
但是重要的是,您需要给您的类一个move构造函数-默认值是可以的:
Tester(Tester&&) = default;
这是必需的,因为当向量调整自身大小时,它们需要移动或复制其元素。通常会为您创建一个移动构造函数,但在您的情况下,使用自定义析构函数将阻止该构造函数。参见here。
这将使您的代码编译,但随后它将在运行时引发异常。这是因为有时您会从Testers
中移出,这会在线程移出时调用join。幸运的是,这很容易解决:
~Tester()
{
if(th.joinable())
th.join();
}
完整的工作代码:
#include <iostream>
#include <thread>
#include <vector>
#include <functional>
#include <unistd.h>
class Tester
{
public:
Tester(std::function<void(void)> func) :
th(func)
{
}
~Tester()
{
if(th.joinable())
th.join();
}
Tester(Tester&&) = default;
private:
std::thread th;
};
std::vector<Tester> testers;
void InnerHelloWorld()
{
std::cout << "Hello from the inner word!\n";
}
int main() {
std::cout << "Hello World!\n";
for(size_t i = 0 ; i < 4 ; i++)
{
testers.emplace_back(InnerHelloWorld);
}
sleep(1);
return 0;
}
答案 1 :(得分:3)
您需要为您的类定义move构造函数,以使其变为 MoveInsertable 并满足emplace
方法的要求:
Tester(Tester && other) :
th(::std::move(other.th))
{
}
一旦解决了缺少移动构造函数的问题,另一个问题是试图加入不是必须加入的线程,因为实际的线程可能已经移入了另一个对象。因此,您需要添加相应的检查:
~Tester()
{
if(th.joinable())
{
th.join();
}
}