原文地址
如初化
{
if (Foo * ptr = get_foo())
use(*ptr);
more_code();
}
不能转为极 :
{
{
QVariant var = getAnswer();
if (var.isValid())
use(var);
}
more_code();
}
17版本 :
{
if (QVariant var = getAnswer(); var.isValid())use(var);
more_code();
}
猜语句 :
{
switch (Device dev = get_device(); dev.state())
{
case sleep: break;
case ready: break;
case bad: break;
}
}
结构绑定 :
tuple<int, string> func();
auto [ i, s ] = func();
use(s, ++i);
编译成:
pair<int, string> func();
auto __tmp = func();
auto & i = get<0>(__tmp);
auto & s = get<1>(__tmp);
use(s, ++i);
即使auto [i,s] = func(); 没& ,也是引用.如:
#include <string>
#include <iostream>
struct Foo
{
int x = 0;
std::string str = "world";
~Foo() { std::cout << str; }
};
int main()
{
auto [ i, s ] = Foo();
std::cout << "你好";
s = "结构绑定";
}
#include <string>
#include <iostream>
struct Foo
{
int x = 0;
std::string str = "world";
~Foo() { std::cout << str; }
};
int main()
{
auto __tmp = Foo();
std::cout << "你好";
__tmp.str = "结构绑定";
}
输出为你好结构绑定 .注意s = "结构绑定"; 在临变量内部 修改Foo::str ,所以析构器打印结构绑定 .& 用来应用至隐藏的临时变量 .
struct X { int i = 0; };
X makeX();
X x;
auto [ b ] = makeX();
b++;
auto const [ c ] = makeX();
c++;
auto & [ d ] = makeX();
d++;
auto & [ e ] = x;
e++;
auto const & [ f ] = makeX();
f++;
struct X { int i = 0; };
X makeX();
X x;
auto __tmp1 = makeX();
__tmp1.i++;
auto const __tmp2 = makeX();
__tmp2.i++;
auto & __tmp3 = makeX();
auto & _tmp3 = x;
x.i++;
auto const & _tmp4 = makeX();
__tmp4.i++;
编译器尽量用get<N>() ,所以可直接同构 用.
struct Foo {
int x;
string str;
};
Foo func();
auto [ i, s ] = func();
use(s, ++i);
struct Foo {
int x;
string str;
};
Foo func();
Foo __tmp = func();
auto & i = __tmp.x;
auto & s = __tmp.str;
use(s, ++i);
实现自己的get() ,tuple_size ,tuple_element ,对默认情况下不行的任何类/构 ,要实现自己的自定义get<>() 并且还要实现tuple_size 和tuple_element .
class Foo {
public:
template <int N> auto & get() { }
};
template<int N> auto & get(Foo & foo) { }
namespace std {
template<> struct tuple_size<Foo> { static const int value = 3; }
template<int N> struct tuple_element<N, Foo> { using type = 加代码; }
}
Foo func();
auto [ i, s ] = func();
use(s, ++i);
数组.
int arr[4] = { };
auto [ a, b, c, d ] = arr;
auto [ t, u, v ] = std::array<int,3>();
for (auto && [key, value] : my_map)
{
}
如常式 .
class Foo {
int myInt;
string myString;
public:
int const & refInt() const
{ return myInt; }
string const & refString() const
{ return myString; }
};
namespace std
{
template<> class tuple_size<Foo>
: public integral_constant<int, 2>
{ };
template<int N> class tuple_element<N, Foo>
{
public:
using type =
conditional_t<N==0,int const &,string const &>;
};
}
template<int N> auto & get(Foo const & foo)
{
static_assert(0 <= N && N < 2, "仅有2成员");
if constexpr (N == 0)
return foo.refInt();
else if constexpr (N == 1)
return foo.refString();
}
如 常式(式) ,式 必须为常式 ,否则编译不过. 推导:
pair<int, string> is1 = pair(17, "hello");
auto is2 = pair(17, "hello");
auto is3 = pair(17, string("hello"));
auto is4 = pair(17, "hello"s);
隐式/显式 推导.显式 :
template<typename T>
struct Thingy
{
T t;
};
Thingy(const char *) -> Thingy<std::string>;
Thingy thing{"串"};
元<类 T, 类 U, ...> 构/类... 隐式推导类型 元<动> .
template <auto v>
struct integral_constant
{
static constexpr auto value = v;
};
integral_constant<2048>::value
integral_constant<'a'>::value
折叠表达式
auto x = sum(5, 8);
auto y = sum(a, b, 17, 3.14, ...);
template <typename... Args>
auto sum(Args&&... args) {
return (args + ... + 0);
}
嵌套名字空间
namespace A::B::C {
struct Foo { };
}
单参输出:
static_assert(sizeof(short) == 2)
内联变量:
inline int foo = 10;
struct Foo {
static inline int foo = 10;
};
保证省略复制
namespace std
{
template <typename M>
struct lock_guard
{
explicit lock_guard(M & mutex);
lock_guard(lock_guard const & ) = delete;
}
}
lock_guard<mutex> grab_lock(mutex & mtx)
{
return lock_guard<mutex>(mtx);
}
mutex mtx;
void foo()
{
auto guard = grab_lock(mtx);
}
新[[属性]] ,直降
switch (device.status())
{
case sleep:
device.wake();
[[fallthrough]];
case ready:
device.run();
break;
case bad:
handle_error();
break;
}
不丢 :
struct SomeInts
{
[[nodiscard]] bool empty();
void push_back(int);
};
void random_fill(SomeInts & container,
int min, int max, int count)
{
container.empty();
for (int num : gen_rand(min, max, count))
container.push_back(num);
}
类/构 上:
struct [[nodiscard]] MyError {
std::string message;
int code;
};
MyError divide(int a, int b) {
if (b == 0) {
return {"除0", -1};
}
std::cout << (a / b) << '\n';
return {};
}
divide(1, 2);
要小心使用不丢 .
[[maybe_unused]] bool res = step1();
assert(res);
step2();
etc();
可能未用 函数:
[[maybe_unused]] void f()
{
}
int main()
{
}
std::string_view 串视,标准化现有实践. 假设编写了某种解析器:
Foo parseFoo(std::string const & input);
但是后来一些用户用char * 并创建了个string 来传递给解析器,所以加(或改为) 这个接口:
Foo parseFoo(char const * str);
该接口太有用 ,用户加至自己的,且最后无尾 .
Foo parseFoo(char const * str, int length);
我们又用了自定义的串:
Foo parseFoo(MyString const & str);
如何维护这些接口呢?
Foo parseFoo(std::string_view input);
Foo parseFoo(char const * str, int length)
{
return parseFoo(string_view(str,length));
}
class MyString {
operator string_view() const
{
return string_view(this->data, this->length);
}
};
2示例
解析xml ,不断返回串 ,每个串都是分配,因而用串视 .注意,串视不拥有但指向 串内存.为引用语义 . 标::可选<T>
Foo parseFoo(std::string_view input);
std::optional<Foo> parseFoo(std::string_view in);
或者:
if (optional ofoo = parseFoo(str); ofoo)
use(*ofoo);
optional<int> oi = parseInt(str);
std::cout << oi.value_or(0);
更完美联 :std::variant<A,B,C,...> .
struct Stuff
{
std::variant<int, double, string> data;
};
用法:
void handleData(int i);
void handleData(double d);
void handleData(string const & s);
std::visit([](auto const & val) { handleData(val); }, stuff.data);
用λ 来搞:
struct ThatLambda
{
void operator()(int const & i) { handleData(i); }
void operator()(double const & d) { handleData(d); }
void operator()(string const & s) { handleData(s); }
};
ThatLambda thatLambda;
std::visit(thatLambda, stuff.data);
更多:
if (holds_alternative<int>(data))
int i = get<int>(data);
double d = get<double>(data);
std::variant<Foo, Bar> var;
Bar bar = makeBar();
var = bar;
var = Foo();
var = someFoo;
std::variant<Foo, std::string> foostr;
foostr="hello";
std::any ,任何.
std::any v = ...;
if (v.type() == typeid(int)) {
int i = any_cast<int>(v);
}
std::any 不是模板,运行时更改类型.
std::vector<any> things;
上面可容纳Circles,Squares,Triangles,ints,strings,... 等等. 文系:
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
void copy_foobar() {
fs::path dir = "/";
dir /= "sandbox";
fs::path p = dir / "foobar.txt";
fs::path copy = p;
copy += ".bak";
fs::copy(p, copy);
fs::path dir_copy = dir;
dir_copy += ".bak";
fs::copy(dir, dir_copy, fs::copy_options::recursive);
}
void display_contents(fs::path const & p) {
std::cout << p.filename() << "\n";
if (!fs::is_directory(p))
return;
for (auto const & e: fs::directory_iterator{p}) {
if (fs::is_regular_file(e.status())) {
std::cout << " " << e.path().filename()
<< " [" << fs::file_size(e) << " 字节]\n";
} else if (fs::is_directory(e.status())) {
std::cout << " " << e.path().filename() << "\n";
}
}
}
大量并行算法(69 )个:
1 | 2 | 3 |
---|
adjacent_difference | is_heap_until | replace_copy_if | adjacent_find | is_partitioned | replace_if | all_of | is_sorted | reverse | any_of | is_sorted_until | reverse_copy | copy | lexicographical_compare | rotate | copy_if | max_element | rotate_copy | copy_n | merge | search | count | min_element | search_n | count_if | minmax_element | set_difference | equal | mismatch | set_intersection | fill | move | set_symmetric_difference | fill_n | none_of | set_union | find | nth_element | sort | find_end | partial_sort | stable_partition | find_first_of | partial_sort_copy | stable_sort | find_if | partition | swap_ranges | find_if_not | partition_copy | transform | generate | remove | uninitialized_copy | generate_n | remove_copy | uninitialized_copy_n | includes | remove_copy_if | uninitialized_fill | inner_product | remove_if | uninitialized_fill_n | inplace_merge | replace | unique | is_heap | replace_copy | unique_copy |
并行 使用方法:
std::for_each(std::execution::par, first, last,
[](auto & x){ process(x); }
);
std::copy(std::execution::par, first, last, output);
std::sort(std::execution::par, first, last);
std::transform(std::execution::par_unseq, xfirst, xlast, yfirst,
[=](double xi, double yi){ return a * xi + yi; }
);
执行策略,下面的原文不好翻译,要注意 :
策略 | 意思 |
---|
std::execution::seq | 调用线程不确定有序 (线程内重排) | std::execution::par | 多线程 调用,线程内(重排),线程间 并行. | std::execution::par_unseq | 多线程可能向量化 ,调用间无序 ,且可能交错 .这是放松模式 . |
技规
在std::experimental 里面.概念 ,现在已是标准 .
template <RandomAccessIterator T>
auto binarySearch(T first, T second)
{
}
后面,没啥了.
|