std::function<>
;函数using CartesianControl = std::function<CartesianPose(RCI::robot::RobotState robot_state)>;
std::function是一个函数包装模板,可以包装下列这几种可调用元素类型:函数、函数指针、类成员函数指针或任意类型的函数对象
std::function对象可被拷贝和转移,并且可以使用指定的调用特征来直接调用目标元素
举例
最基本的,std::function 是一个模板类,模板参数是一个类型(注意是一个类型,不是好几个类型)。我们可以这么写:
std::function<int(double)> f;
f 是一个可调用对象,参数为 double,返回值为 int 。你也许会问,这里既规定了参数类型又规定了返回值类型,怎么就成了一个类型呢?确实是一个类型,int(double) 是一个函数类型(注意不是函数指针)。
std::function 要包装所有合适类型的对象,就必须有对应的构造函数,所以这是个模板构造函数。参数不是通用引用而是直接传值:
template <typename F>
function(F);
这里让我想到了OpenCV中的ORB::create();
Ptr智能指针模板类
Ptr是OpenCV中使用的智能指针模板类,可以轻松管理各种类型的指针
Ptr<FeatureDetector> detector = ORB::create();
//等价于
FeatureDetector * detector = ORB::create();
//创建一个Ptr类型的detector,用于接收ORB类中create()函数的返回值
ORB::create()函数
opencv中的ORB类是一个纯虚类,继承于Feature2D类,无法进行实例化创建对象。提供静态成员函数ORB::create()供调用
Ptr<ORB> orb=ORB::create(500);
orb->detectAndCompute(image, Mat(), keypoints, descriptors);
lambda
函数**[](){}
**lambda函数(匿名函数)
基本lambda语法
基本形式如下:
[capture](parameters)->return-type {body}
[]叫做捕获说明符,表示一个lambda表达式的开始
lambda函数能够捕获lambda函数外的具有自动存储时期的变量。函数体与这些变量的集合合起来叫闭包。
[] 不截取任何变量
[&} 截取外部作用域中所有变量,并作为引用在函数体中使用
[=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
[=, &foo] 截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
[bar] 截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
[x, &y] x按值传递,y按引用传递
[this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项
接下来是参数列表,即这个匿名的lambda函数的参数
->return-type表示返回类型,如果没有返回类型,则可以省略这部分
最后是函数体部分
可以这样输出"hello,world"
auto func = [] () { cout << "hello,world"; };
func(); // now call the function
CartesianControl cartesian_position_callback;
cartesian_position_callback = [&](RCI::robot::RobotState robot_state) -> CartesianPose {
time += 0.001;
if(init==true){
init_position = robot_state.toolTobase_pos_m;
init_psi = robot_state.psi_m;
init=false;
}
constexpr double kRadius = 0.2;
double angle = M_PI / 4 * (1 - std::cos(M_PI / 5 * time));
double delta_x = kRadius * std::sin(angle);
double delta_z = kRadius * (std::cos(angle) - 1);
CartesianPose output{};
output.toolTobase_pos_c = init_position;
output.toolTobase_pos_c[11]+=delta_z;
output.psi_c = init_psi;
return output;
};
robot.Control(cartesian_position_callback);
template<>
;函数它可以实现类型参数化,把类型定义为参数(模板元编程),从而实现了真正的代码可重用性
模板是一种对类型进行参数化的工具;
通常有两种形式:函数模板和类模板;
函数模板针对仅参数类型不同的函数;
类模板针对仅数据成员和成员函数类型不同的类。
使用模板的目的就是能够让程序员编写与类型无关的代码。比如编写了一个交换两个整型int 类型的swap函数,这个函数就只能实现int 型,对double,字符这些类型无法实现,要实现这些类型的交换就要重新编写另一个swap函数。使用模板的目的就是要让这程序的实现与类型无关,比如一个swap模板函数,即可以实现int 型,又可以实现double型的交换。模板可以应用于函数和类。下面分别介绍。
注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板
// 定义一个函数模板或者类模板。
//通过这种形式将原本函数或者类中固定的型别参数化
//在编译的过程中
//编译器将会根据实际的情况的去为我们自动生成对应型别的代码,从而实现的代码复用。
#include <iostream>
template<typename T>
T add(T x, T y)
{
return x + y;
}
int main()
{
int x1 = 0, y1 = 1;
auto result1 = add(x1, y1);
std::cout << result1 << std::endl;
float x2 = 0.0f, y2 = 1.0f;
auto result2 = add(x2, y2);
std::cout << result2 << std::endl;
return 0;
}
//对于类模板而言,也与函数模板相同
// 在编译环节编译器会用不同型别去实例化模板获得最终的实体。
//但是有一点与函数模板不同
//类模板的在调用的时候必须显示的指出所使用的型别而函数模板
//可以选择显示指出或者不指出直接让编译器自己推导所需要的数据类型
作者:iwtbam
链接:https://www.jianshu.com/p/fc3fe1e01b42
来源:简书
#include <iostream>
template<typename T>
class A
{
public:
T getV() const { return V; }
private:
T V;
};
template<typename T>
T add(T x, T y)
{
return x + y;
}
template<typename T1, typename T2>
T1 minus(T2 x, T2 y)
{
return x - y;
}
int main()
{
A<int> a;
// A a;
// 报错
// main.cpp:27:7: error: missing template arguments before ‘a’
auto sum = add(4, 3);
auto r = minus<float>(10, 5);
// auto r = minus(10, 5);
// 报错
// main.cpp:31:25: error: no matching function for call to ‘minus(int, int)’
// auto r = minus(10, 5);
// ^
// main.cpp:19:4: note: candidate: template T1 minus(T2, T2)
// T1 minus(T2 x, T2 y)
// ^~~~~
// main.cpp:19:4: note: template argument deduction/substitution failed:
// main.cpp:31:25: note: couldn't deduce template parameter ‘T1’
// auto r = minus(10, 5);
// ^
return 0;
}
gettimeofday()
函数// 计时函数
#include<sys/time.h>
struct timeval start_tv;
gettimeofday(&start_tv, NULL);
需要统计时间的算法
struct timeval end_tv;
gettimeofday(&end_tv, NULL);
double timeuse=end_tv.tv_sec*1000.0-start_tv.tv_sec*1000.0+(end_tv.tv_usec-start_tv.tv_usec)/1000.0;
cout<<"time use:"<<timeuse<<"ms"<<endl;