C++标准库随着标准的制订,功能越来越丰富,让程序大大减少对第三方库的依赖,更好的支持多种平台。自己对比较有用的标准库进行了代码测试,供自己查找和大家参考,共同学习进步,废话不多说,直接上代码。
#include <stdio.h>
#include <string>
#include <IOStream>#include <list>#include <vector>#include <map>#include <mutex>#include <shared_mutex>#include <atomic>#include <condition_variable>#include <thread>#include <future>#include <algorithm>#include <unordered_map>#include <regex>#include <locale>#include <codecvt>#include <functional>#if _HAS_CXX17
#include <string_view>#endif // _HAS_CXX17#include <memory>#include <array>#include <typeinfo>// autovoid cpp11_auto(){ // C++11: auto关键字,自动类型
// 32位整数
// auto j; auto i = 100;
printf("auto i = %dn", i);
// 64位整数
auto j = 100000000000LL;
printf("auto j = %lldLLn", j);
// 结构体 struct Data { int data = 0; };
auto p = new Data(); p->data = 234234;
printf("auto p = new Data(), p->data = %d.n", p->data);
delete p; // 容器 std::map<std::string, int> kv;
kv["k1"] = 1;
kv["k2"] = 2;
kv["k3"] = 3;
std::map<std::string, int>::iterator iter = kv.begin();
for(auto it = begin(kv); it != end(kv); it ++)
{ printf("<%s, %d>n", it->first.c_str(), it->second);
}}struct S_OBJ{ int a; int b;};// loopsvoid cpp11_loops(){ // C++11: 区间迭代
std::vector<int> sv; sv.push_back(100);
sv.push_back(200);
sv.push_back(300);
for(int &v : sv)
{ printf("v = %dn", v);
v ++; } for(auto &v : sv)
{ printf("auto v = %dn", v);
} std::map<std::string, int> kv = { { "k1", 1 }, { "k2", 2 }, { "k3", 3 } };
for(const auto& it : kv)
{ printf("<%s, %d>n", it.first.c_str(), it.second);
} std::string str1 = "AbsdfasdfWQErqsadfasdf@!5235safdsaASDFASDF";
std::for_each(str1.begin(), str1.end(), [](const char &c)
{ printf("%c", c);
}); std::transform(str1.begin(), str1.end(), str1.begin(), [](int c) -> int
{ return std::tolower(c);
}); std::transform(str1.begin(), str1.end(), str1.begin(), ::toupper);
/* static constexpr struct S_OBJ obj = { .a = 2000,
.b = 10 * 1000
};*/}// enumvoid cpp11_enum(){ // C++11: 强类型枚举
enum class Options : int64_t { None = 1, One, Two, Three, All };
Options o1 = Options::All; Options o2 = Options::Two;}// Lambdavoid cpp11_lambda(){ // C++11: Lambda表达式,匿名函数
{ // 基本Lambda语法 auto func = [](int i, const std::string &s)
{ printf("%d, %sn", i, s.c_str());
return 0;
}; func(100, "lambda");
} { // 变量捕获 1
int i = 10000;
auto j = 1.0;
auto func1 = [&](const std::string &s)
{ printf("%d, %f, %sn", i, j, s.c_str());
}; auto func = [&](const std::string &s)
{ printf("%d, %f, %sn", i, j, s.c_str());
func1("sdfsadf");
}; func("lambda");
} { // 变量捕获 2
class C { public : C() { a = 1111; }
void f(int b) { auto func = [&](const std::string &s)
{ printf("%d, %d, %sn", a, b, s.c_str());
}; func("lambda");
} private: int a; }; C c; c.f(44444);
} { // 返回值 auto func1 = [](int i) { return i*100; };
int ret1 = func1(1);
auto func2 = [](int i) -> int { return i*10000; };
int ret2 = func2(2);
} { // for_each std::vector<int> v = { 100, 200, 300 };
std::for_each(std::begin(v), std::end(v), [](int n)
{ printf("%dn", n);
}); auto value = std::find_if(std::begin(v), std::end(v),
[](int n) { return n == 100; });
if(value != std::end(v))
{ printf("value = %dn", *value);
} else
{ printf("not foundn");
} }/* [] 不捕获任何变量 [&] 以引用方式捕获所有变量 [=] 用值的方式捕获所有变量(可能被编译器优化为const &) [=, &i] 以引用捕获foo, 但其余变量都靠值捕获 [bar] 以值方式捕获bar; 不捕获其它变量 [this] 捕获所在类的this指针*/}// mutex & atomicvoid cpp11_mutex_atomic(){ // C++11: 互斥量和原子变量
{ int value = 1000;
// 递归锁 std::recursive_mutex mutex1; mutex1.lock(); value = 20000;
mutex1.unlock(); { std::lock_guard<std::recursive_mutex> lock(mutex1); value -= 200;
} { std::unique_lock<std::recursive_mutex> lock(mutex1); value += 200;
} } { // 时间递归锁 std::recursive_timed_mutex mutex2; { if(mutex2.try_lock_for(std::chrono::milliseconds(200)))
{ printf("lock.n");
mutex2.unlock(); } } } { // 读写锁 std::shared_mutex mutex3; int i = 100;
mutex3.lock(); i ++; mutex3.unlock(); { std::unique_lock<std::shared_mutex> locker(mutex3); i ++; } mutex3.lock_shared(); int j = i; mutex3.unlock_shared(); { std::shared_lock<std::shared_mutex> locker(mutex3); j = i; } }/* std::mutex 最基本的 Mutex 类。 std::recursive_mutex 递归 Mutex 类。 std::time_mutex 定时 Mutex 类。 std::recursive_timed_mutex 定时递归 Mutex 类。 std::shared_mutex 读写锁 Mutex*/ // 原子变量 std::atomic<int> a = 1000;
std::atomic<bool> b = true;
a ++; b = false;
}// conditionstatic std::mutex sm;static std::condition_variable sc;void a_thread(){ std::unique_lock<std::mutex> lock(sm); printf("thread - waiting signal...n");
sc.wait(lock); printf("thread - received signal...n");
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
lock.unlock(); printf("thread - notify signal...n");
sc.notify_one();}void cpp11_condition(){ std::thread at(a_thread); { std::this_thread::sleep_for(std::chrono::milliseconds(1000));
} printf("main - notify signal...n");
sc.notify_one(); { std::unique_lock<std::mutex> lock(sm); sc.wait(lock); printf("main - received signal...n");
} at.join(); printf("main - thread exit...n");
}// threadvoid thread_proc(int a, int b){ printf("a = %dn", a);
}void cpp11_thread(){ // C++11: std::thread 线程
std::thread aThread = std::thread([]() -> int { std::this_thread::sleep_for(std::chrono::milliseconds(100));
return 1;
}); if(aThread.joinable())
{ aThread.join(); } std::thread threads[5];
for(int i = 0; i < 5; i ++)
{ threads[i] = std::thread(thread_proc, i, 100);
} for(auto& t : threads)
{ t.join(); }}void cpp11_future(){ // C++11: std::future 可以用来获取异步任务的结果
// std::launch::async: 直接创建线程 // std::launch::deferred: 延迟创建线程(当遇到future.get或者future.wait的时候才会创建线程) // 默认为std::launch::async | std::launch::deferred // 这个就不可控了,由操作系统根据当时的运行环境来确定是当前创建线程还是延迟创建线程。 std::future<int> f = std::async(std::launch::async, [](int a) { std::this_thread::sleep_for(std::chrono::seconds(2));
return a;
}, 100);
// 阻塞一直等待结果返回 int a = f.get(); printf("a = %dn", a);
}void cpp11_class(){ class Base { public: // Base() = default; // 缺省构造 Base() { value1 = 0;
value2 = 2;
} // 委托构造函数 Base(int value) : Base() { value2 = value; } virtual int foo1() { return value2;
} virtual int foo2(int a) final { return a;
} private: int value1 = 0;
int value2 = 2;
}; Base base(3);
class Sub1Class final : Base { public: using Base::Base; // 继承构造 int foo1() override { return 2;
} // virtual int foo2(int a) override { return a * 2; } // 非法, Base的foo2函数已是final
// virtual int foo5(float) override { return 0; } // 非法, 父类没有此虚函数
}; // class Sub2Class : Sub1Class {}; // 非法, Sub1Class 已 final Sub1Class s1(4);
}void cpp11_regex(){ std::string fnames[] = { "foo.txt", "bar.txt", "bar.exe", "test", "a0bc.txt", "AAA.txt" };
{ std::regex base_match("[a-z]+\.txt");
for(const auto &fname : fnames)
{ bool ret = std::regex_match(fname, base_match); printf("%s:%sn", fname.c_str(), ret ? "true" : "false");
} } { std::regex base_regex("([a-z]+)\.([a-z]+)");
for(const auto &fname : fnames)
{ std::smatch base_match; bool ret = std::regex_match(fname, base_match, base_regex); if(ret)
{ // sub_match 的第一个元素匹配整个字符串 // sub_match 的第二个元素匹配了第一个括号表达式 if(base_match.size() == 3)
{ printf("sub-match[0] : %s, sub-match[1] : %s, sub-match[2] : %sn",
base_match[0].str().c_str(), base_match[1].str().c_str(), base_match[2].str().c_str());
} } } }}const std::string wstring2utf8(const std::wstring& src)
{ std::wstring_convert<std::codecvt_utf8<wchar_t>> conv; return conv.to_bytes(src);
}const std::wstring utf8_2_wstring(const std::string& src)
{ std::wstring_convert<std::codecvt_utf8<wchar_t> > conv; return conv.from_bytes(src);
}void cpp11_wstring_utf8(){ // codecvt_utf8 : <ucs-2 | ucs-4> <=> utf-8
// codecvt_utf8_utf16 : utf-16 <=> utf-8
// codecvt_utf16 : <ucs-2 | ucs-4> <=> <utf-16le | utf-16be>
std::string strUTF8 = wstring2utf8(L"测试codecvt代码");
std::wstring wstrUCS1 = utf8_2_wstring(strUTF8); std::wstring wstrUCS2 = utf8_2_wstring(u8"这是UTF-8字符串");
wprintf(L"UCS1:%snUCS2:%sn", wstrUCS1.c_str(), wstrUCS2.c_str());
return ;
}int func1(int, const char*)
{ return 0;
}void cpp11_functional(){ // C++11: std::function的实例可以对任何可以调用的目标实体进行存储、复制、和调用操作
// 这些目标实体包括普通函数、Lambda表达式、函数指针、以及其它函数对象等
auto callback = [](std::function<int(int, const char*)> func)
{ return func(100, "string");
}; std::function<int(int, const char*)> func;
func = func1; func(1, "sdfsdf");
callback([](int v, const char *str)
{ printf("%d,%sn", v, str);
return 0;
}); class MyBase { public: virtual int print2(int v, const char *str) {return 0; }
}; class MyFunc:public MyBase { public: static int print(int v, const char *str)
{ printf("MyFunc::print(%d, %s)n", v, str);
return 0;
} int print2(int v, const char *str)
{ MyBase::print2(v, str); printf("MyFunc::print2(%d, %s)n", v, str);
return 0;
} }; callback(&MyFunc::print);
MyBase *mb1 = new MyFunc(); MyFunc my1; mb1->print2(1, "df");
// 使用std::placeholders::_1, std::placeholders::_2对参数进行占位 callback(std::bind(&MyBase::print2, &my1, std::placeholders::_1, std::placeholders::_2)); (&my1)->MyBase::print2(100, "a string");
std::function<int(int, const char*)> func2 =
std::bind(&MyFunc::print2, &my1, std::placeholders::_1, std::placeholders::_2); func2(1000, "a string");
// std::ref, std::cref, 在模板传参的时候传入引用,否则无法传递 auto test_function = [](std::function<void(int)> fun)
{ fun(1);
}; auto foo1 = [](int& a) -> void { ++ a; }; auto foo2 = [](const int& a) { std::cout << "a=" << a << "n";
}; int a = 1;
// 变量a被复制,并没有对a引用 auto f1 = std::bind(foo1, a); test_function(f1); std::cout << "a=" << a << "n";
// std::ref 是一个函数,返回 std::reference_wrApper(类似于指针) test_function(std::bind(foo1, std::ref(a))); std::cout << "a=" << a << "n";
test_function(std::bind(foo2, std::cref(a))); std::cout << "a=" << a << "n";
}void cpp11_move(){ // C++11: move construct, 移动构造(&&),减少内存分配和复制
std::string str1 = "this is a string.";
std::cout << "str1:" << str1 << std::endl;
std::string str2(std::move(str1));
std::cout << "str2:" << str2 << std::endl;
std::cout << "str1:" << str1 << std::endl;
std::vector<int> vec1{ 1, 2, 3, 4, 5 };
std::vector<int> vec2(std::move(vec1)); std::cout << "vec1:" << vec1.size() << std::endl;
std::cout << "vec2:" << vec2.size() << std::endl;
std::cout << "vec1:" << vec1.size() << std::endl;
// 减少内存拷贝和移动, 向容器中中加入临时对象,临时对象原地构造,没有赋值或移动的操作。 std::vector<std::string> vec;
vec.push_back("this is a text.");
vec.emplace_back("this is a text.");
}void cpp11_shared_ptr(){ // C++11: 智能指针, 允许多个指针指向同一个对象
std::shared_ptr<int> s1(new int(100));
std::shared_ptr<int> s2(s1); //s1.reset(); //s1 = nullptr; auto s3 = std::make_shared<int>(200);
bool isEqual = (s1 == s2); printf("s1:%d, s2:%d, s3:%d, s1 == s2:%sn", *s1, *s2, *s3, isEqual ? "y" : "n");
class MySharedClass : public std::enable_shared_from_this<MySharedClass> { public: MySharedClass() { } virtual ~MySharedClass() { } public: void p() { printf("%pn", this);
} std::shared_ptr<MySharedClass> getSharedPtr() { return shared_from_this();
} }; std::shared_ptr<MySharedClass> p1(new MySharedClass()); std::shared_ptr<MySharedClass> p2 = p1; printf("use count:%dn", p2.use_count());
// 使用std::make_shared可以消除显式的使用 new auto p3 = std::make_shared<MySharedClass>(); p1->p(); p2->p(); p3->p(); p3.reset(); // 计数器减1
auto deleteMySharedClass = [](MySharedClass *p) { delete p; }; // 自定义内存释放函数 std::shared_ptr<MySharedClass> p4(new MySharedClass(), deleteMySharedClass); p4->p(); auto p5(std::move(p4)); p4->p(); p4 = nullptr; // 计数器减1
// 独占的智能指针, 引用计数为0或1,不能共享
std::unique_ptr<int> up1(new int(500));
// std::unique_ptr<int> up2(up1); // error
printf("up1:%dn", *up1);
std::unique_ptr<int> up2(std::move(up1)); int* upv = up2.release(); delete upv;}void cpp17_string_view(){#if _HAS_CXX17
// string_view是C++17引用的类库,避免内存复制
std::string_view sv("cpp17 string view");
auto s1 = sv.substr(0, 10);
const char *str = sv.data();
auto str2 = std::string(str, sv.length());
for(auto c : s1)
{ } // 调用substr并不会分配新的内存,只是引用原内存地址 std::cout << s1 << std::endl;#endif // _HAS_CXX17}void cpp11_others(){ { // 参数初始化 std::map<std::string, int> m{ {"a", 1}, {"b", 2}, {"c", 3} };
for(const auto &kv : m)
{ std::cout << kv.first << " : " << kv.second << std::endl;
} std::vector<int> iv{5, 4, 3, 2, 1};
iv.push_back(6);
// array 常量数组 std::array<int, 4> ary = { 1, 2, 3, 4 };
ary.empty(); // 检查容器是否为空 ary.size(); // 返回容纳的元素数 std::sort(ary.begin(), ary.end(), [](int a, int b)
{ return b < a;
}); } { // std::this_thread::yield() 当前线程让出自己的CPU时间片(给其他线程使用)
// std::this_thread::sleep_for() 休眠一段时间. std::atomic<bool> ready(false);
while(!ready)
{ // std::this_thread::yield();
for(int i = 0; i < 5; i ++)
{ std::this_thread::sleep_for(std::chrono::milliseconds(100));
} ready = true;
} } { // high resolution clock
std::chrono::time_point<std::chrono::high_resolution_clock> ct1 = std::chrono::high_resolution_clock::now(); std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::chrono::time_point<std::chrono::high_resolution_clock> ct2 = std::chrono::high_resolution_clock::now(); int64_t systemClock1 = std::chrono::duration_cast<std::chrono::milliseconds>(ct1 - std::chrono::time_point<std::chrono::high_resolution_clock>()).count(); int64_t systemClock2 = std::chrono::duration_cast<std::chrono::milliseconds>(ct2 - std::chrono::time_point<std::chrono::high_resolution_clock>()).count(); int64_t sleepMS = std::chrono::duration_cast<std::chrono::milliseconds>(ct2 - ct1).count(); int64_t sleepUS = std::chrono::duration_cast<std::chrono::microseconds>(ct2 - ct1).count(); std::cout << "sleep milliseconds : " << sleepMS << ", sleep microseconds : " << sleepUS << std::endl;
using hrc = std::chrono::high_resolution_clock; std::chrono::time_point<hrc> ct3 = hrc::now(); } { // 元组 auto t1 = std::make_tuple(10, "string", 3.14);
//std::type_info ti = (int); std::vector<decltype(t1)> veco1; printf("tuple : %d, %s, %.3fn", std::get<0>(t1), std::get<1>(t1), std::get<2>(t1));
std::get<1>(t1) = "text";
// 对tuple解包 int v1 = std::get<0>(t1);
std::string v2;
double v3; std::tie(v1, v2, v3) = t1; printf("tie(%d, %s, %.3f)n", v1, v2.c_str(), v3);
std::tuple<double, std::string> t2(3.1415926, "pi");
} { // std::unordered_map, std::unordered_set std::map<std::string, int> m1;
m1["b"] = 2;
m1["c"] = 3;
m1["a"] = 1;
for(const auto &v : m1)
{ std::cout << v.first << ":" << v.second << std::endl;
} std::unordered_map<std::string, int> m2;
m2["b"] = 2;
m2["c"] = 3;
m2["a"] = 1;
for(const auto &v : m2)
{ std::cout << v.first << ":" << v.second << std::endl;
} } { auto x = 1;
auto y = 2;
// 推导返回类型 using type = decltype(x+y);
type z; // int
z = 100;
std::cout << z << std::endl; } { // 原始字符串字面量 std::string str = R"(C:\What\The\Fxxksdfsadf345'''23'47523*"(""/'\""")";
std::cout << str << std::endl; // C:\What\The\Fxxksdfsadf345'''23'47523*"/'\"""
// 支持3种UNICODE编码: UTF-8, UTF-16, 和 UTF-32
const char u1[] = u8"I'm a UTF-8 string.u2018";
const char16_t u2[] = u"This is a UTF-16 string.u2018";
const char32_t u3[] = U"This is a UTF-32 string.U00002018";
} { // to string or wstring
auto v = std::to_wstring(1000);
std::cout << std::to_string(1000) << ", " << std::to_string(3.1352345) << std::endl;
} { typedef void(*FunctionType)(double); // 老式语法 using FunctionType = void(*)(double); // 新式语法 } { // nullptr and NULL
int a = NULL; // int a = nullptr; // 编译错误 void *p = nullptr; class MyNullPtr { public: void func(int a) { printf("func(int) is called.n");
} void func(const char* a)
{ printf("func(const char*) is called.n");
} }; MyNullPtr ptr; ptr.func(0);
ptr.func(NULL); ptr.func(nullptr); } { // constexpr,常量表达式 int len = 10;
// char buffer[len]; // 编译报错
const int b = 10 + 5*2;
const int a = 10 + 5*2 + b;
constexpr int len2 = 10 + 50*2 + a;
char buffer2[a]; // 合法
} { // 左值引用和右值引用(&&) std::string str1 = "string,"; // lv1 是一个左值
// std::string&& str2 = str1; // 非法, 右值引用不能引用左值
std::string&& str3 = std::move(str1); // 合法, std::move可以将左值转移为右值
std::string&& str4 = str1 + str3; // 合法, 右值引用延长临时对象生命周期
str4 += "Test"; // 合法, 非常量引用能够修改临时变量
} { int i = 0;
std::string str1 = "string,"; // lv1 是一个左值
const std::type_info& info1 = typeid(i); printf("typeinfo:%s, %sn", info1.name(), info1.raw_name());
const std::type_info& info2 = typeid(&str1); printf("typeinfo:%s, %sn", info2.name(), info2.raw_name());
}}int main(int argc, char *argv[])
{ setlocale(LC_ALL, "zh_CN.UTF-8");
// auto类型推导 cpp11_auto(); // 区间迭代 cpp11_loops(); // 强类型枚举 cpp11_enum(); // Lambda表达式 cpp11_lambda(); // 互斥量和原子变量 cpp11_mutex_atomic(); // 条件变量 cpp11_condition(); // thread,线程 cpp11_thread(); // 异步任务处理 cpp11_future(); // 正则表达式 cpp11_regex(); // 字符串相关 cpp11_wstring_utf8(); // 函数调用 cpp11_functional(); // 移动构造 cpp11_move(); // 共享指针 cpp11_shared_ptr(); // class新的特性 cpp11_class(); // string_view(C++17)
cpp17_string_view(); // 其他一些实用方法 cpp11_others(); return 0;
}