/*
* @Author: your name
* @Date: 2022-01-02 10:32:09
* @LastEditTime: 2022-01-02 11:44:31
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \qt_project\c++17\main.cpp
*/
#include <iostream>
#include <any>
#include <variant>
#include <string_view>
#include <map>
#include <filesystem>
#include <set>
#include <algorithm>
#include <numeric>
#include <execution>
#include <execution>
#include <functional>
//if constexpr
template <int N, int... Ns>
auto sum()
{
if constexpr (0 == sizeof...(Ns)) //编译期判断参数为空返回N
return N;
else //需要else,不能去掉
return N + sum<Ns...>(); //不为空进行递归
}
//折叠表达式
template<typename ...Ns> //任意参数个数,...表达参数包 return后面的()表示自己调用自己递归
auto sum(Ns... ns) {
//一元折叠表达式 右折叠
return (ns + ...); //ns示每个参数,...表示参数解包,ns在+号左边表示右折叠 (((1 + 2) + 3) + 4) + 5
//一元折叠表达式 左折叠
return (... + ns); //ns示每个参数,...表示参数解包,ns在+号左边表示左折叠 1 + (2 + (3 + (4 + 5)))
//二元折叠表达式 右折叠
return (0 + ... + ns);; //默认有一个参数0
//二元折叠表达式 右左折叠
return (ns + ... + 0); //默认有一个参数0
}
int main()
{
//string_view 提供字条串视图,减少拷贝
std::cout << "-----------------------------" << std::endl;
std::string str(" hello, world ");
std::string_view viewStr(str);
std::cout << viewStr.substr(viewStr.find_first_not_of(' ')) << std::endl;
std::cout << "-----------------------------" << std::endl;
//提供文件系统管理
#ifdef WIN32
std::cout << std::filesystem::current_path() << std::endl;
std::filesystem::create_directories("sandbox/a");
for (auto& p : std::filesystem::recursive_directory_iterator(std::filesystem::current_path().string() + "/../b"))
{
std::cout << p.is_directory() << " " << p.path() << std::endl;
}
//目标目录或文件存在、源目录/文件不存在,会abort
std::filesystem::copy(std::filesystem::current_path().string() + "/../b", std::filesystem::current_path().string() + "/b"); //目录拷贝
bool ok = std::filesystem::copy_file(std::filesystem::current_path().string() + "/../bb", std::filesystem::current_path().string() + "/xx"); //文件拷贝
ok = std::filesystem::remove(std::filesystem::current_path().string() + "/../dd");
#else
//g++ 9.3以下
#include <experimental/filesystem>
std::cout << std::experimental::filesystem::current_path() << std::endl;
std::experimental::filesystem::create_directories("sandbox/a");
for (auto& p : std::experimental::filesystem::recursive_directory_iterator(std::filesystem::current_path().string() + "/../b"))
{
std::cout << p.status().type() << " " << p.path() << std::endl;
}
std::filesystem::experimental::copy(std::experimental::filesystem::current_path().string() + "/../b", std::experimental::filesystem::current_path().string() + "/b"); //目录拷贝
std::filesystem::experimental::copy_file(std::experimental::filesystem::current_path().string() + "/../bb", std::experimental::filesystem::current_path().string() + "/xx"); //文件拷贝
bool ok = std::experimental::filesystem::remove(std::experimental::filesystem::current_path().string() + "/../dd");
//编译加上链接参数 -lstdc++fs
//g++ 9.3以上和windows一样
#endif
std::cout << "-----------------------------" << std::endl;
//提供any类型,可以创建任意类型的数据
std::vector<std::any> anyVec{ "chare", 234234, 342.34534, std::pair(342,23), std::tuple(34, "sdf", 3423.232) };
for (auto &anyValue : anyVec)
{
std::cout << anyValue.type().name() << std::endl;
}
std::cout << "-----------------------------" << std::endl;
// //提供variant共用体
std::variant<int, float> v, w; //std::variant是共用体union类型
v = 12; // v contains int
int i = std::get<int>(v);
w = std::get<int>(v);
w = std::get<0>(v); // same effect as the previous line
w = v; // same effect as the previous line
// std::get<double>(v); // error: no double in [int, float]
// std::get<3>(v); // error: valid index values are 0 and 1
try
{
float f = std::get<float>(w); // w contains int, not float: will throw
}
catch (std::bad_variant_access&)
{
}
// //determine the type of variant
if (v.index() == 1) {
// it's float type
std::wcout << L"var2 is float type" << std::endl;
}
std::variant<std::string> v2("abc"); // converting constructors work when unambiguous
v2 = "def";
std::cout << "-----------------------------" << std::endl; // converting assignment also works when unambiguous
// //结构化绑定
std::map<int, std::string> mapValue{ {32,"fer"}, {343,"erwe"},{2389,"ewr"} };
for (auto &[key, value] : mapValue) {
std::cout << key << " " << value << std::endl;
}
std::vector<std::tuple<int, std::string, std::string>> tupleVec{ {45,"fe","123"},{454,"erw","ewrw"},{898,"fwer","werew"} };
for (auto &[value1, value2, value3] : tupleVec) {
std::cout << value1 << " " << value2 << " " << value3 << std::endl;
}
// //if语句内置变量声明
if (int a = std::min(3, 5); a < 9) {
std::cout << a << " is less than 9" << std::endl;
}
else {
std::cout << a << " is larger than 9" << std::endl;
}
std::set<std::string> stringSet{ "feriji" };
if (auto[iter, success] = stringSet.insert("aaa"); success) { //insert返回迭代器位置和操作是否成功,结构化绑定到初始变量中
std::cout << *iter << std::endl; // aaa
}
else
{
std::cout << "insert failed" << std::endl; // aaa
}
// //if constexpr(expression) 编译期对进行判断
std::cout << sum<1, 2, 3>() << std::endl;
// //可变参数模板增加折叠表达式 https://www.jianshu.com/p/4bf4d1860588 https://blog.csdn.net/ding_yingzi/article/details/79973809
std::cout << sum<1, 2, 3>() << std::endl;
// //增加的STL算法 std::for_each_n, std::exclusive_scan, std::inclusive_scan, std::transfom_exclusive_scan , std::transform_inclusive_scan, std::reduce and std::transform_reduce
// //std::for_each更新
// // for_each_n
std::vector<int> intVec{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 1
std::for_each_n(std::execution::par, // 2 前n个数进行for_each
intVec.begin(), 5, [](int& arg) { arg *= arg; });
std::cout << "for_each_n: ";
for (auto v : intVec) std::cout << v << " ";
std::cout << "\n\n";
// // exclusive_scan and inclusive_scan
std::vector<int> resVec{ 4, 2, 3, 4, 5, 6, 7, 8, 9 };
std::exclusive_scan(std::execution::par, // 3
resVec.begin(), resVec.end(), resVec.begin(), 10, //第一个元素就是初始值10, 从第二个开始依次乘以前面的数,最后一个元素不进行计算;前一次的结果会做为后一次的第一个参数
[](int fir, int sec) { return fir * sec; }); //10 10*4 10*4*2 10*4*2*3 ... 10*4*2*...*8
std::cout << "exclusive_scan: ";
for (auto v : resVec) std::cout << v << " ";
std::cout << std::endl;
std::vector<int> resVec2{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::inclusive_scan(std::execution::par, // 5
resVec2.begin(), resVec2.end(), resVec2.begin(), //第一个元素就是初始值10 * resV2的第一个元素, 最后一个元素包含在内进行计算;前一次的结果会做为后一次的第一个参数
[](int fir, int sec) { return fir * sec; }, 10); //10*1, 10*1*2, 10*1*2*3, .. ,10*1*2*3*...*9
std::cout << "inclusive_scan: ";
for (auto v : resVec2) std::cout << v << " ";
std::cout << "\n\n";
// // transform_exclusive_scan and transform_inclusive_scan
std::vector<int> resVec3{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> resVec4(resVec3.size());
std::transform_exclusive_scan(std::execution::par, // 6
resVec3.begin(), resVec3.end(),
resVec4.begin(), 0,
[](int fir, int sec) { return fir + sec; },
[](int arg) { return arg *= arg; });
std::cout << "transform_exclusive_scan: ";
for (auto v : resVec4) std::cout << v << " ";
std::cout << std::endl;
std::vector<std::string> strVec{ "Only", "for", "testing", "purpose" }; // 7
std::vector<int> resVec5(strVec.size());
std::transform_inclusive_scan(std::execution::par, // 8
strVec.begin(), strVec.end(),
resVec5.begin(),
[](auto fir, auto sec) { return fir + sec; },
[](auto s) { return s.length(); });
std::cout << "transform_inclusive_scan: ";
for (auto v : resVec5) std::cout << v << " ";
std::cout << "\n\n";
// reduce and transform_reduce
std::vector<std::string> strVec2{ "Only", "for", "testing", "purpose" };
std::string res = std::reduce(std::execution::par, // 9 std::reduce前一次计算的结果,做为后一次的参数
strVec2.begin() + 1, strVec2.end(), strVec2[0],
[](auto fir, auto sec) { return fir + ":" + sec; });
std::cout << "reduce: " << res << std::endl;
// 11
// std::execution::seq
// 调用者线程单线程方式,以不确定的顺序访问元素
// std::execution::par
// 多线程(由库隐式的创建线程)方式,在每个线程中,以不确定的顺序访问元素
// std::execution::par_unseq
// multiple threads and may be vectorized - calls are unsequenced with respect to each other and possibly interleaved
std::size_t res7 = std::transform_reduce(std::execution::par, //std::execution::par可能会自己创建线程协助完成运算 http://www.cnblogs.com/thomas76/p/8554668.html
strVec2.begin(), strVec2.end(), size_t(0),
[](std::size_t a, std::size_t b) { std::cout << "threadId " << std::this_thread::get_id() << std::endl; return a + b; },
[](std::string s) { return s.length(); }
);
std::cout << "transform_reduce: " << res7 << std::endl;
return 0;
int arr[100000];
std::for_each(std::execution::par, arr, arr + 10000, [](auto & x) { std::cout << "threadId " << std::this_thread::get_id(); x * 3 / 2 + 5 - 8; }); //根据打印即可看到出现了多个线程,需要考虑加锁或者使用原子变量
//加锁处理
int a[] = { 0,1,3,4,5,6,7,8,9 };
std::vector<int> vtest;
std::mutex m;
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i) {
std::lock_guard<std::mutex> guard(m); //互斥量保护v
vtest.push_back(i * 2 + 1);
});
int _tmp[5]={0};
char __c[3]={0};
//iota c++11就添加了,以做备忘
std::iota(_tmp, _tmp+5, 10); //changes a to {10,11,12,13,14}
std::iota(__c, __c+3, 'a'); //{'a','b','c'}
//c++ stl函数说明 https://zh.cppreference.com/w/cpp/algorithm
return 0;
}
c++17功能示例全览
最新推荐文章于 2024-08-20 09:12:41 发布