// 使用输入输出流
#include <iostream> //标准输入输出头文件
#include <sstream>
float x_trans = 0.7;
if(argc>=2) {
std::istringstream xss(argv[1]);
xss >> x_trans;
}
// 使用库函数 整数等转string
int j=100;
string j_str = boost::chrono::to_string(j)
在vector中查找最先想到的自然是find函数
struct student{
string name;
int grade;
};
vector<student> stu;//就当数据已经存好了...
假设以name为查找对象
string str="john";
vector<student>::iterator it=find(stu.begin(),stu.end(),str);
此时迭代器it指示的就是我们查找的字符串所在的结构体在容器中的位置,但是这显然是会出错的。
find的本质是将find的第三个参数与容器中的元素进行==操作,string和student不管怎么样都不会相等的。
所以我们需要将student的==操作重写
bool student::operator ==(const string &x){
return(this->name==x);
}
// 在结构体vector中查找符合条件的所有元素
// g++ test.cpp -o t
// ./t
#include<iostream>
#include<vector>
#include<iterator>
#include<algorithm>
#include<string>
using namespace std;
typedef struct StudentInfo {
int id;
string name;
} STUINFO;
// 奇数
bool IsOddId (STUINFO info) {
return ((info.id%2)==1);
}
// 偶数
bool IsEvenId (STUINFO info) {
return ((info.id%2)==0);
}
int main(int argc, char** argv)
{
vector<STUINFO> v;
vector<STUINFO>::iterator iter, it_end;
STUINFO temp;
temp.id = 100;
temp.name = "Jack";
v.push_back(temp);
temp.id = 101;
temp.name = "Sam";
v.push_back(temp);
temp.id = 102;
temp.name = "John";
v.push_back(temp);
temp.id = 103;
temp.name = "Tom";
v.push_back(temp);
std::vector<vector<STUINFO>::iterator> candidate; // 符合条件的
iter = v.begin()-1;
it_end = v.end();
while(true)
{
// iter = find_if(++iter, v.end(), IsEvenId);// 偶数
iter = find_if(++iter, v.end(), IsOddId); // 奇数
if (iter != it_end )
// cout << "ID: " << (*iter).id << ", Name: " << (*iter).name <<endl;
candidate.push_back(iter);
else
break;
}
for(int i=0; i<candidate.size(); i++)
cout << "ID: " << (*candidate[i]).id << ", Name: " << (*candidate[i]).name <<endl;
return 0;
}
linux无锁化编程--__sync_fetch_and_add系列原子操作函数
// 以count = 4为例,调用__sync_fetch_and_add(&count,1),之后,返回值是4,然后,count变成了5.
// 有 __sync_fetch_and_add , 自然也就有 __sync_add_and_fetch,呵呵这个的意思就很清楚了,先自加,再返回。
// 他们哥俩的关系与i++和++i的关系是一样的。
// 有了这个宝贝函数,我们就有新的解决办法了。对于多线程对全局变量进行自加,我们就再也不用理线程锁了。
在用gcc编译的时候要加上选项 -march=i686
// sam:在我的服务器上,发现不加都可以。
type __sync_fetch_and_add (type *ptr, type value);
type __sync_fetch_and_sub (type *ptr, type value);
type __sync_fetch_and_or (type *ptr, type value);
type __sync_fetch_and_and (type *ptr, type value);
type __sync_fetch_and_xor (type *ptr, type value);
type __sync_fetch_and_nand (type *ptr, type value);
type __sync_add_and_fetch (type *ptr, type value);
type __sync_sub_and_fetch (type *ptr, type value);
type __sync_or_and_fetch (type *ptr, type value);
type __sync_and_and_fetch (type *ptr, type value);
type __sync_xor_and_fetch (type *ptr, type value);
type __sync_nand_and_fetch (type *ptr, type value);
//http://blog.csdn.net/devfun/article/details/6534476
//https://blog.csdn.net/devfun/article/details/6534476
int* RandPerm(int N)
{
int i;
int[] TempArray = new int[N];
int[] Value = new resultArray[N];
for (i = 0; i < N; i++)
TempArray[i] = i;// 0~n-1数组
for (i = 0; i < N; i++)
{
int seed = random(0, N - i);//从剩下的随机数里生成
resultArray[i] = TempArray[seed];//赋值给结果数组
TempArray[seed] = TempArray[N - i - 1];//把随机数产生过的位置替换为未被选中的值。
}
return resultArray;
}
我们都知道main函数是C语言的入口函数,代码都是从main函数开始执行的。
那么问题来了,有没有办法让代码在main函数之前执行哪?
GCC语法支持的__attribute__属性
__attribute__((constructor)):在main函数之前执行某个函数;类似类的构造函数。
__attribute__((destructor)):在main函数之后执行某个函数;类似类的析构函数。
constructor和destructor会在ELF文件中添加两个段-.ctors和.dtors。
当动态库或程序在加载时,会检查是否存在这两个段,如果存在执行对应的代码。
#include <stdio.h>
void __attribute__((constructor)) before_main();
void __attribute__((destructor)) after_main();
int main()
{
printf("Hello World!\n");
return 0;
}
void before_main()
{
printf("Before main\n");
}
void after_main()
{
printf("After main\n");
}
/*
Before main
Hello World!
After main
*/
// 浮点数判等
bool is_equal (double a, double b, double epsilon = 1.0e-7)
{
return std::abs(a - b) < epsilon;
}
// 等于零
bool NearZero(const double val, double epsilon = 1.0e-6){
return (std::abs(val) < epsilon);
}
int atoi_my(const char* const cs) {
// 内置 atoi 不会处理 NULL 指针
if (cs == nullptr) return 0;
int ret = 0;
auto *p = cs; // cs 为常指针
// 跳过前面的空格
while (isspace(*p)) p++;
// 判断正负
int sign = 1; // 默认正数
if (*p == '-') sign = -1;
if (*p == '-' || *p == '+') p++;
// 核心代码:循环转换整数(加入溢出判断)=============================
int tmp; // 保存临时结果,用于溢出判断
while (*p >= '0' && *p <= '9') {
tmp = ret * 10 + (*p - '0');
if (tmp / 10 != ret) { // 溢出判断======== tmp/10的商 应该等于 ret====
return sign > 0 ? INT_MAX : INT_MIN; // 溢出时,直接返回最大值 或最小值
}
ret = tmp;
p++;
}
// 核心代码(无溢出判断)
//while (*p >= '0' && *p <= '9') {
// ret = ret * 10 + (*p - '0');
// p++;
//}
return sign * ret;
}
友元函数
不是类的成员函数,却能访问该类所有成员(包括私有成员)的函数
类授予它的友元函数特别的访问权,这样该友元函数就能访问到类中的所有成员。
class A {
public:
friend void set_data(int x, A &a); // 类A的友元函数 的声明
int get_data() { return data; }
private:
int data;
};
void set_data(int x, A &a) { // 友元函数的定义
a.data = x;
cout << a.data << endl; // 该友元函数 可以 无障碍 读写 A类 的私有成员
}
int main(void) {
class A a;
set_data(1, a);
// cout << a.data; // err
cout << a.get_data() << endl;
return 0;
}
友元类
一个类的 友元类 可以访问 该类的所有成员(包括私有成员)
注意点
友元关系不能被继承
友元关系不能传递
友元关系是单向的
class A {
public:
friend class C; // A类的 友元类 C 的声明:C 是 A 的友元类
private:
int data;
};
class C { // 友元类C 的定义,可以访问 类A 中的成员
public:
void set_A_data(int x, A &a) {
a.data = x;
}
int get_A_data(A& a) {
return a.data;
}
};
int main(void) {
class A a;
class C c;
c.set_A_data(1, a);
cout << c.get_A_data(a) << endl; // 1
return 0;
}
// 矩阵归一化,归一化矩阵
Eigen::MatrixXd Normalize(Eigen::MatrixXd V){
V.normalize();
return V;
}
// 向量转李代数,叉乘矩阵,反对称矩阵
Eigen::Matrix3d VecToso3(const Eigen::Vector3d& omg) {
Eigen::Matrix3d m_ret;
m_ret << 0, -omg(2), omg(1),
omg(2), 0, -omg(0),
-omg(1), omg(0), 0;
return m_ret;
}
// 李代数矩阵(反对称矩阵) 转 向量
Eigen::Vector3d so3ToVec(const Eigen::MatrixXd& so3mat) {
Eigen::Vector3d v_ret;
v_ret << so3mat(2,1), so3mat(0,2), so3mat(1,0);
return v_ret;
}
// 归一化向量+模
Eigen::Vector4d AxisAng3(const Eigen::Vector3d& expc3){
Eigen::Vector4d v_ret;
v_ret << Normalize(expc3), expc3.norm();
return v_ret;
}
// 机器人相关库
https://github.com/Le0nX/ModernRoboticsCpp/blob/master/src/modern_robotics.cpp
//去除无法追踪的特征 输入特征点的状态标识数组
void reduceVector(vector<cv::Point2f> &v, vector<uchar> status)
{
int j = 0;// j为剩余 状态良好的 特征点数量
for (int i = 0; i < int(v.size()); i++)
if (status[i]) // 特征点状态良好
v[j++] = v[i];//j++表示先取出j的值,再加1
// j为剩余 状态良好的 特征点数量
v.resize(j);
}
//去除无法追踪到的特征点 特征点id数组 ;特征点的状态标识数组
void reduceVector(vector<int> &v, vector<uchar> status)
{
int j = 0;// j为剩余 状态良好的 特征点数量
for (int i = 0; i < int(v.size()); i++)
if (status[i]) // 特征点状态良好
v[j++] = v[i];//j++表示先取出j的值,再加1
// j为剩余 状态良好的 特征点数量
v.resize(j);
}
//(cnt, pts, id)序列 追踪的次数:2d特征点:特征点id
vector<pair<int, pair<cv::Point2f, int>>> cnt_pts_id;
for (unsigned int i = 0; i < forw_pts.size(); i++)
cnt_pts_id.push_back(make_pair(track_cnt[i], make_pair(forw_pts[i], ids[i])));
//对光流跟踪到的特征点forw_pts,按照被跟踪到的次数从大到小排序
sort(cnt_pts_id.begin(), cnt_pts_id.end(),
// 匿名函数 实现 两元素比较大小
[](const pair<int, pair<cv::Point2f, int>> &a, const pair<int, pair<cv::Point2f, int>> &b)
{
return a.first > b.first;
}
);
// 结构体数据中 某项数据的范围
auto cmp_x = [](PointXYZPixel const& l, PointXYZPixel const& r) { return l.x < r.x; };
auto minmax_x = std::minmax_element(seg->begin(), seg->end(), cmp_x);// 点云x最大
// 结构体数据中某一项的均值
auto sum_x = [](double sum_x, PointXYZPixel const& l){return sum_x + l.x;};// 对某一项累计求和
auto sumx = std::accumulate(seg->begin(), seg->end(), 0.0, sum_x);// 求和
double mean_x = sumx / seg->size(); // 均值
// 使用 外部数据(类内私有数据)
// 判断点云团是否足够大===
auto func = [this](pcl::PointIndices indices) { return indices.indices.size() < this->mObject_minimum_points; };
// 删除过小的点云团
cluster_indices.erase(std::remove_if(cluster_indices.begin(), cluster_indices.end(), func), cluster_indices.end());