常用算法函数
常用算法函数
1 all_of、any_of、none_of
void Test()
{
vector<int> vecData = { 1, 6, 5, 7, 9 };
auto pFunIsEven = [](int nValue)
{
if (0 == nValue % 2)
return true;
return false;
};
bool bResult = false;
// 所有的都需要满足
bResult = std::all_of(vecData.begin(), vecData.end(), pFunIsEven);
qDebug() << "all_of Result = " << bResult;
// 任意一个满足即可
bResult = std::any_of(vecData.begin(), vecData.end(), pFunIsEven);
qDebug() << "any_of Result = " << bResult;
// 所有的都不满足
bResult = std::none_of(vecData.begin(), vecData.end(), pFunIsEven);
qDebug() << "none_of Result = " << bResult;
}
2 find_if、find_if_not
void Test()
{
vector<int> vecData = { 1, 6, 5, 7, 9 };
auto pFunIsEven = [](int nValue)
{
if (0 == nValue % 2)
return true;
return false;
};
bool bResult = false;
// 找到第一个满足要求的元素
auto pFind = std::find_if(vecData.begin(), vecData.end(), pFunIsEven);
qDebug() << "find_if *pFind = " << *pFind;
// 找到第一个不满足要求的元素
pFind = std::find_if_not(vecData.begin(), vecData.end(), pFunIsEven);
qDebug() << "find_if_not *pFind = = " << *pFind;
}
3 copy_if
void Test()
{
vector<int> vSrc = { 1, 3, 5, 7, 9, 4 };
// 保证拷贝的目的容器够大,防止数组越界
std::vector<int> vDes(vSrc.size());
auto it = std::copy_if(vSrc.begin(), vSrc.end(), vDes.begin(),
[](int nValue){ return 0 != (nValue % 2); });
qDebug() << "*it = " << *it;
// 将容器缩减合适
vDes.resize(std::distance(vDes.begin(), it));
qDebug() << "Des vector size = " << vDes.size();
}
4 itoa
用于方便生成有序序列,在某个基础之上+1递增
void Test()
{
vector<int> vData(5);
std::iota(vData.begin(), vData.end(), 5); // 5是初始值
std::array<int, 5> aData;
std::iota(aData.begin(), aData.end(), 5);
}
5 minmax_element
void Test()
{
vector<int> vData { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto result = std::minmax_element(vData.begin(), vData.end());
qDebug() << "min *result.first = " << *result.first;
qDebug() << "max *result.second = " << *result.second;
}
6 is_sorted & is_sorted_until
is_sorted:用来判断某个序列是否是排序好的
is_sorted_until:用来返回序列中前面已经排好的序列
void Test()
{
vector<int> vData { 1, 2, 5, 7, 9, 4 };
bool bIsSorted = std::is_sorted(vData.begin(), vData.end());
auto itPos = std::is_sorted_until(vData.begin(), vData.end());
for (auto it = vData.begin(); it != itPos; ++it)
qDebug() << "*it = " << *it;
}
7 委托构造函数
struct MyData
{
int m_nMax;
int m_nMin;
int m_nMiddle;
MyData(int nMax, int nMin)
{
m_nMax = nMax;
m_nMin = nMin;
}
// 委托构造函数,委托构造函数不能使用类成员变量初始化
MyData(int nMax, int nMin, int nMiddle): MyData(nMax, nMin)
{
m_nMiddle = nMiddle;
}
}
8 使用 using 继承构造函数
使用 using 继承构造函数,普通的成员函数也适用
struct Base
{
int m_nA;
int m_nB;
int m_nC;
Base(int nA, int nB, int nC) : m_nA(nA), m_nB(nB), m_nC(nC)
{
// ...
}
void Fun()
{
qDebug() << "Base Fun";
qDebug() << "m_nA = " << m_nA;
qDebug() << "m_nB = " << m_nB;
qDebug() << "m_nC = " << m_nC;
}
}
struct Derived : Base
{
using Base::Base; // 使用基类的构造函数
using Base::Fun; // 使用基类的成员函数
void Fun(int nValue)
{
qDebug() << "Derived Fun";
qDebug() << "Value = " << nValue;
}
}
void Test()
{
Derived d(1.0, 2.0, 3.0); // 使用了基类的构造函数
d.Fun(10);
d.Fun();
}
9 原始字面量
语法格式:R"xxx(raw string)xxx"
其中原始字符串必须用括号()起来,括号前后可以添加其他字符串,所加的字符串是会被忽略的,而且加的字符串必须在括号两边同事出现;
void Test()
{
std::string strA("D:\A\B\test.text");
std::string strB("D:\\A\\B\\test.text");
std::string strC(R"Path(D:\A\B\test.text)Path"); // Path 也可以不加
qDebug() << "strA = " << strA.c_str();
qDebug() << "strB = " << strB.c_str();
qDebug() << "strC = " << strC.c_str();
}
10 final 和 override 标志符
final关键字
- 用于限制某个类不能被继承
- 用于限制某个虚函数不能被重写(只能用于限制虚函数,限制普通函数会报错)
struct A
{
virtual void Fun() final;
};
struct B final: A
{
};
void A::Fun()
{
qDebug() << "A Fun!";
}
void Test()
{
A a;
a.Fun();
}
override 确保在派生类中声明的重写函数与基类的虚函数有相同的签名,同事也明确表明将会重写基类的虚函数;
struct A
{
virtual void Fun() = 0;
};
struct B: A
{
void Fun() override;
};
11 使用 alignas 指定内存对齐大小
alignas需要一个编译期数值
- 指定常规数据类型
void TestAD()
{
alignas(32) long long d = 10;
}
- 指定自定义类型
#define XX 1
struct alignas(XX) MyStruct_1{}
template <size_t YY = 1>
struct alignas(YY) MyStruct_2{}
static const int ZZ = 1;
struct alignas(ZZ) MyStruct_3{}
alignas 只能改大,不能改小,如果需要改小,需要使用 # pragma pack
_Pragma("pack(1)")
struct MyStructA
{
char a;
int b;
double c;
char e;
};
_Pragma("pack()")
void TestAC()
{
MyStructA myA;
qDebug() << "&myA = " << &myA;
}
12 使用 alignof 和 alignment_of 获取内存对齐的大小
alignof 用来获取内存对齐大小
_Pragma("pack(1)")
struct MyStructA
{
char a;
int b;
double c;
char e;
};
_Pragma("pack()")
struct MyStructB
{
int x;
int y;
}
void Test()
{
MyStructA myA;
MyStructB myB;
qDebug() << "myA Size = " << alignof(myA);
qDebug() << "myB Size = " << alignof(myB);
qDebug() << "MyStructA Size = " << alignof(MyStructA);
qDebug() << "MyStructB Size = " << alignof(MyStructB);
}
alignment_of 的用法
struct MyStructAA
{
char a;
int b;
double c;
};
void Test()
{
qDebug() << "Size = " << std::alignment_of<MyStructAA>::value;
}
13 内存对齐的类型:aligned_storage
aligned_storage 可以看成一个内存对齐的缓冲区
一般和 placement new 结合使用
struct AB
{
int avg;
AB(int nA, int nB):avg((nA + nB) / 2)
{
// ...
}
}
using Aligned_AB = std::aligned_storage<sizeof(AB), alignof(AB)>::type;
void Test()
{
Aligned_AB a, b;
new (&a) AB(10, 20);
b = a;
qDebug() << "average = " << reinterpret_cast<AB&>(b).avg;
}