[1]namespace,即“命名空间”:
二.由于namespace的概念,使用C++标准程序库的任何标识符时,可以有三种选择:
[2] c++ for_each
相当于一个函数模板:
template<typename InputIterator, typename Function> Function for_each(InputIterator beg, InputIterator end, Function f) { while(beg != end) f(*beg++); }
template< class InputIt, class UnaryFunction > UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f ); (1) template< class ExecutionPolicy, class ForwardIt, class UnaryFunction2 > void for_each( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, UnaryFunction2 f ); (2)
Parameters
first, last ---the range to apply the function to.
policy---the execution policy to use. See execution policy for details.
f--- function object, to be applied to the result of dereferencing every iterator in the range [first, last)
The signature of the function should be equivalent to the following:
void fun(const Type &a);
The signature does not need to have const &.
The type Type must be such that an object of type InputIt can be dereferenced and then implicitly converted to Type.
[3] Eigen: C++开源矩阵计算工具
Eigen中关于矩阵类的模板函数中,共有6个模板参数,但是目前常用的只有前三个(分别表示矩阵元素的类型,行数和列数),如下所示:
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> struct traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > .......
《视觉SLAM十四讲》e.g.:
#include <iostream> using namespace std; #include <ctime> // Eigen 部分 #include <Eigen/Core> // 稠密矩阵的代数运算(逆,特征值等) #include <Eigen/Dense> #define MATRIX_SIZE 50 /**************************** * 本程序演示了 Eigen 基本类型的使用 ****************************/ int main( int argc, char** argv ) { // Eigen 中所有向量和矩阵都是Eigen::Matrix,它是一个模板类。它的前三个参数为:数据类型,行,列 // 声明一个2*3的float矩阵 Eigen::Matrix<float, 2, 3> matrix_23; // 同时,Eigen 通过 typedef 提供了许多内置类型,不过底层仍是Eigen::Matrix // 例如 Vector3d 实质上是 Eigen::Matrix<double, 3, 1>,即三维向量 Eigen::Vector3d v_3d; // 这是一样的 Eigen::Matrix<float,3,1> vd_3d; // Matrix3d 实质上是 Eigen::Matrix<double, 3, 3> Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero(); //初始化为零 // 如果不确定矩阵大小,可以使用动态大小的矩阵 Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > matrix_dynamic; // 更简单的 Eigen::MatrixXd matrix_x; // 这种类型还有很多,我们不一一列举 // 下面是对Eigen阵的操作 // 输入数据(初始化) matrix_23 << 1, 2, 3, 4, 5, 6; // 输出 cout << matrix_23 << endl; // 用()访问矩阵中的元素 for (int i=0; i<2; i++) { for (int j=0; j<3; j++) cout<<matrix_23(i,j)<<"\t"; cout<<endl; } // 矩阵和向量相乘(实际上仍是矩阵和矩阵) v_3d << 3, 2, 1; //向量 vd_3d << 4,5,6; //矩阵 // 但是在Eigen里你不能混合两种不同类型的矩阵,像这样是错的 // Eigen::Matrix<double, 2, 1> result_wrong_type = matrix_23 * v_3d; // 应该显式转换 Eigen::Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d; cout << result << endl; Eigen::Matrix<float, 2, 1> result2 = matrix_23 * vd_3d; cout << result2 << endl; // 同样你不能搞错矩阵的维度 // 试着取消下面的注释,看看Eigen会报什么错 // Eigen::Matrix<double, 2, 3> result_wrong_dimension = matrix_23.cast<double>() * v_3d; // 一些矩阵运算 // 四则运算就不演示了,直接用+-*/即可。 matrix_33 = Eigen::Matrix3d::Random(); // 随机数矩阵 cout << matrix_33 << endl << endl; cout << matrix_33.transpose() << endl; // 转置 cout << matrix_33.sum() << endl; // 各元素和 cout << matrix_33.trace() << endl; // 迹 cout << 10*matrix_33 << endl; // 数乘 cout << matrix_33.inverse() << endl; // 逆 cout << matrix_33.determinant() << endl; // 行列式 // 特征值,特征向量 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver ( matrix_33 ); cout << "Eigen values = \n" << eigen_solver.eigenvalues() << endl; cout << "Eigen vectors = \n" << eigen_solver.eigenvectors() << endl; // 解方程 // 我们求解 matrix_NN * x = v_Nd 这个方程 // N的大小在前边的宏里定义,它由随机数生成 // 直接求逆自然是最直接的,但是求逆运算量大 Eigen::Matrix< double, MATRIX_SIZE, MATRIX_SIZE > matrix_NN; matrix_NN = Eigen::MatrixXd::Random( MATRIX_SIZE, MATRIX_SIZE ); Eigen::Matrix< double, MATRIX_SIZE, 1> v_Nd; v_Nd = Eigen::MatrixXd::Random( MATRIX_SIZE,1 ); clock_t time_stt = clock(); // 计时 // 直接求逆 Eigen::Matrix<double,MATRIX_SIZE,1> x = matrix_NN.inverse()*v_Nd; cout <<"time use in normal invers is " << 1000* (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms"<< endl; // 通常用矩阵分解来求,例如QR分解,速度会快很多 time_stt = clock(); x = matrix_NN.colPivHouseholderQr().solve(v_Nd); cout <<"time use in Qr compsition is " <<1000* (clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms" << endl; return 0; }
[5]push_back用法
如果是指标准模板库(stl)中容器的一般pushback()操作函数,那么是指在容器尾端插入一项数据,比如
vector<int> a(10);
a.pushback(10);
那么a的尾端,同时也是唯一一个数据a[0]就会为设置为10。
函数原型 void push_back(value_type_Ch);
参数 _Ch-->The character to beadded to the end of the string. 在vector类中: voidpush_back(const_Ty&_X) { insert(end(),_X); }
在vector<_Bool, _Bool_allocator>类中: voidpush_back(constbool_X) { insert(end(),_X); }
[5]C++ [stl_vector.h]之iterator
https://www.cnblogs.com/yc_sunniwell/archive/2010/06/25/1764934.html
[6]std::nth_element
C++ Algorithm library Defined in header <algorithm> template< class RandomIt > void nth_element( RandomIt first, RandomIt nth, RandomIt last ); (1)
template< class ExecutionPolicy, class RandomIt > void nth_element( ExecutionPolicy&& policy, RandomIt first, RandomIt nth, RandomIt last ); (2) (since C++17)
template< class RandomIt, class Compare > void nth_element( RandomIt first, RandomIt nth, RandomIt last, Compare comp ); (3)
template< class ExecutionPolicy, class RandomIt, class Compare > void nth_element( ExecutionPolicy&& policy, RandomIt first, RandomIt nth, RandomIt last, Compare comp ); (4) (since C++17)
nth_element(first, nth, last, compare)
求[first, last]这个区间中第n大小的元素,如果参数加入了compare函数,就按compare函数的方式比较。
nth_element仅排序第n个元素(从0开始索引),即将位置n(从0开始)的元素放在第n大的位置,处理完之后,默认排在它前面的元素都不比它大,排在它后面的元素都不比它小。
例如:array[first, last)元素区间,排序后,array[nth]就是第n大的元素(从0开始).
但[first, nth) 和 [nth,last)区间的大小顺序不一定。但是可以确定的是array[nth]一定是整个区间里第n大的元素。
[first,nth)中的元素都是不大于array[nth]的,[nth, last)中的元素都是不小于array[nth]的。
[7]->
->是C语言和C++语言的一个运算符,叫做指向结构体成员运算符,用处是使用一个指向结构体或对象的指针访问其内成员。
一个指针当用来指向一个结构体、对象时,称之为结构体指针或对象指针。结构体指针或对象指针中的值是所指向的结构体或对象的首地址。通过结构体指针或对象指针即可访问该结构体或对象。这需要用到结构体关键字struct和C++类关键字class。
[8]C++ 位运算 & | << >> ^ ~ %
http://blog.csdn.net/fox64194167/article/details/20692645
(1) << 向左移位移
<<简单例子(向左移一位,右边自动补0)
11 << 1 = 22
00001011 << 1
00010110 = 22
相当于二进制的每个数都变成当前值的两倍,结果就是变成当前值的两倍。
n * 2 == (n << 1)
推广下就是(注意可能会溢出)
(2) >> 向右位移
>>简单例子(向右移一位,左边自动补1)
11 >> 1 = 5
00001011 >> 1
00000101 = 5
注意到最后一位的1被干掉了。
比较实用的例子是:
int n = n / 2 等价于 int n = n >> 1 等价于 int n >>= 1
[9]C++ 函数 .reset()
auto &lines = wm[word]; if (!lines) lines.reset(new set <line_no>); lines的类型是shared_ptr<set<line_no>> 如果lines指针位空 reset重置新的一个shared_ptr对象
[10]<math.h>是C标准函数库中的头文件,在C++中一般用<cmath>。此头文件中声明了一系列函数来计算常见的数学运算和变换:
std::abs: 处理int类型的取绝对值
fabs: 处理double类型的取绝对值
fabsf(): 处理float类型的取绝对值
std::fma(x,y,z):x*y+z;
std::sin: 正弦;
std::asin: 反正弦;
std::sinh: 双曲正弦;
std::asinh: 双曲反正弦;
std::cos: 余弦;
std::acos: 反正弦;
std::cosh: 双曲余弦;
std::acosh: 双曲反余弦;
std::tan:正切;
std::atan:反正切;
std::atan2: 反正切;
std::tanh: 双曲正切;
std::atanh: 双曲反正切;
std::sqrt: 计算平方根;
std::cbrt: 计算立方根;
std::hypot: 计算两个数平方的和的平方根;
std::pow:幂运算;
std::ceil: 不小于给定值的最近整数;
std::floor/ floorf/ floorl: 不大于给定值的最近整数;
std::fmod: 两数除法操作的余数(rounded towards zero);
std::trunc: 不大于给定值的最近整数;
std::round: 舍入取整;
std::lround: 舍入取整, 返回long int;
std::llround: 舍入取整, 返回long long int;
std::nearbyint: 使用当前的舍入模式取整(fegetround());
std::remainder: 两数除法操作的余数(rounded to nearest);
std::remquo: 两数除法操作的余数;
std::rint: 使用当前的舍入模式取整(fegetround());
std::lrint: 使用当前的舍入模式取整(fegetround()),返回long int;
std::llrint: 使用当前的舍入模式取整(fegetround()),返回long longint;
std::exp: ex;
std::frexp: 将一个浮点数分解为有效数(significand)及以2为底的幂(x = significand* 2exp);
std::ldexp: x *2exp;
std::exp2: 2x;
std::expm1: ex-1;
std::scalbn: x *FLT_RADIXn;
std::scalbln: x* FLT_RADIXn;
std::log: ln(x);
std::log10: log10(x);
std::modf: 将一个浮点数分解为整数及小数部分;
std::ilogb: 返回以FLT_RADIX为底,|x|的对数值,返回值为整数;
std::log1p: ln(1+x);
std::log2: log2(x);
std::logb: 返回以FLT_RADIX为底,|x|的对数值,返回值为浮点数;
std::erf: 误差函数;
std::erfc: 互补(complementary)误差函数;
std::tgamma: 伽玛函数;
std::lgamma: log-伽玛函数;
std::copysign(x,y):返回x的值及y的正负符号组成的浮点数;
std::nan: Generatequiet NaN;
std::nextafter(x,y): 返回x之后y方向上的下一个可表示值;
std::nexttoward(x,y): 返回x之后y方向上的下一个可表示值;
std::fdim(x,y): Thefunction returns x-y if x>y, and zero otherwise;
std::fmax: 返回较大的值;
std::fmin: 返回较小的值;
std::fpclassify:为浮点值归类,返回一个类型为int的值;
std::isfinite: 检测是否是有限值;
std::isinf: 检测是否是无穷大值;
std::isnan: 检测是否是非数型;
std::isnormal: 检测是否是normal值,neitherinfinity, NaN, zero or subnormal;
std::signbit: 检测是否是负数;
std::isgreater: 检测第一个数是否大于第二个数;
std::isgreaterequal:检测第一个数是否大于或等于第二个数;
std::isless: 检测第一个数是否小于第二个数;
std::islessequal:检测第一个数是否小于或等于第二个数;
std::islessgreater:检测第一个数是否不等于第二个数;
std::isunordered:检测两个浮点数是否是无序的.
[10]C++中的Cast
http://blog.csdn.net/stan1989/article/details/12588279
-
Dynamic_Cast
(1)首先dynamic_cast能够应用于指针转换。
子类指针转换成父类指针,成功;
父类指针转换成子类指针,就分为两种情况:
<a>父类指针p如果真的指向子类对象,那么转换时成功的;
<b>反之,失败,dynamic_cast返回NULL。
(2)其次dynamic_cast能够应用于引用之间的转换(与指针类似)。
子类引用转换成父类引用,成功;
父类引用转换成子类引用,就分为两种情况:
<a>父类引用ob,如果真的指向子类对象,那么转换时成功的;
<b>反之,失败,dynamic_cast,会抛出bad_cast异常
(3)其他将null指针,转换成任何类型的指针;将任何类型的指针转换成void*类型的指针。
-
Static_Cast
Static_cast可以转换相关联的类,可以从子类转换成父类。也能从父类转向子类,但是如果转换的父类指针(或者父类引用)所指向的对象是完整的,那么是没有问题;但是如果所指向的对象并不完整,那么会出现runtime错误。
Static_cast相对于dynamic_cast而言,除了能转换指针和引用,还能应用于任何能够隐式转换的情况。
-
Reinterpret_Cast
reinterpret_cast和上面讲到的两个cast,适用范围更加广泛,它可以适用于任何类型指针之间的转换。
该操作不会去进行动态类型或者静态类型的检测,它仅仅将值强行赋值过去。从某种意义上对编译器进行了一种欺骗,同时也带来了一定的不安全性。所以在使用这个cast的时候,要慎重。下面是这个操作的适用情况:
(1) Int和指针之间的相互转换;
(2) 无关联类指针之间的转换;
(3) 函数指针之间的转换
-
Const_Cast
const_cast如它的名字,它是去除修饰在对象上的const和volatile。
隐式转换,在代码中很难寻找;但是使用C++的这种cast可以轻松的找出,代码中哪里使用强制转换等。
[11].insert https://docs.scipy.org/doc/numpy/reference/generated/numpy.insert.html
numpy.insert(arr, obj, values, axis=None)[source] 在给定索引之前沿给定轴插入值
Parameters:
arr : array_like
Input array.
obj : int, slice or sequence of ints
Object that defines the index or indices before which values is inserted.它定义在插入值之前的索引或索引支持多个插入时,obj是一个标量或一元序列(类似于调用多次插入)。
values : array_like
Values to insert into arr.
axis : int, optional
Axis along which to insert values. 插入值的轴
[12]vector中resize()和reserve()区别
1、***resize(n)
调整容器的长度大小,使其能容纳n个元素。如果n小于容器的当前的size,则删除多出来的元素。否则,添加采用值初始化的元素。
***resize(n,t)
将所有新添加的元素初始化为t。
2、reserve(n)
预分配n个元素的存储空间。
了解这两个函数的区别,首先要搞清楚容器的capacity(容量)与size(长度)的区别。
size指容器当前拥有的元素个数;而capacity则指容器在必须分配新存储空间之前可以存储的元素总数,也可以说是预分配存储空间的大小。
resize()函数和容器的size息息相关。调用resize(n)后,容器的size即为n。至于是否影响capacity,取决于调整后的容器的size是否大于capacity。
reserve()函数和容器的capacity息息相关。调用reserve(n)后,若容器的capacity<n,则重新分配内存空间,从而使得capacity等于n。
如果capacity>=n呢?capacity无变化。
从两个函数的用途可以发现,容器调用resize()函数后,所有的空间都已经初始化了,所以可以直接访问。
而reserve()函数预分配出的空间没有被初始化,所以不可访问。