#pragma once
_Pragma("once")
# C/C++混合编程
#ifdef __cplusplus
extern "C" {
#endif
// 一些c代码
#ifdef __cplusplus
}
#endif
# 继承构造
struct A
{
A(int i) {}
A(double d,int i){}
A(float f,int i,const char* c){}
//...等等系列的构造函数版本
};
old:
struct B:A
{
B(int i):A(i){}
B(double d,int i):A(d,i){}
B(folat f,int i,const char* c):A(f,i,e){}
//......等等好多个和基类构造函数对应的构造函数
};
new:
struct B:A
{
using A::A;
//关于基类各构造函数的继承一句话搞定
//......
};
#regex
std::regex base_regex("([a-z]+)\\.txt");
std::smatch base_match;
for(const auto &fname: fnames) {
if (std::regex_match(fname, base_match, base_regex)) {
// sub_match 的第一个元素匹配整个字符串
// sub_match 的第二个元素匹配了第一个括号表达式
if (base_match.size() == 2) {
std::string base = base_match[1].str();
std::cout << "sub-match[0]: " << base_match[0].str() << std::endl;
std::cout << fname << " sub-match[1]: " << base << std::endl;
}
}
}
#Variadic templates
// C++11
template <typename First, typename... Args>
auto sum(const First first, const Args... args) -> decltype(first) {
const auto values = {first, args...};
return std::accumulate(values.begin(), values.end(), First{0});
}
// C++17
template <typename... Args>
auto sum(Args... args) {
// Unary folding.
return (... + args);
}
template <typename... Args>
bool logicalAnd(Args... args) {
// Binary folding.
return (true && ... && args);
}
bool b = true;
bool& b2 = b;
logicalAnd(b, b2, true); // == true
#Inline namespaces
namespace Program {
namespace Version1 {
int getVersion() { return 1; }
bool isFirstVersion() { return true; }
}
inline namespace Version2 {
int getVersion() { return 2; }
}
}
int version {Program::getVersion()}; // Uses getVersion() from Version2
int oldVersion {Program::Version1::getVersion()}; // Uses getVersion() from Version1
bool firstVersion {Program::isFirstVersion()}; // Does not compile when Version2 is added
# std::move temp
struct Bar {
int a = 1;
};
struct Foo {
Bar getBar() & { return bar; }
Bar getBar() const& { return Bar{}; }
Bar getBar() && { return std::move(Bar{}); }
private:
Bar bar;
};
Foo foo;
auto&& ref = foo.getBar();
ref.a = 10;
# Nested namespaces
namespace A::B::C {
int i;
}
# __has_include
#ifdef __has_include
# if __has_include(<optional>)
# include <optional>
# define have_optional 1
# elif __has_include(<experimental/optional>)
# include <experimental/optional>
# define have_optional 1
# define experimental_optional
# else
# define have_optional 0
# endif
#endif
# std::invoke
template <typename Callable>
class Proxy {
Callable c_;
public:
Proxy(Callable c) : c_{ std::move(c) } {}
template <typename... Args>
decltype(auto) operator()(Args&&... args) {
// ...
return std::invoke(c_, std::forward<Args>(args)...);
}
};
const auto add = [](int x, int y) { return x + y; };
Proxy p{ add };
p(1, 2); // == 3
# std::clamp limitRange
std::clamp(0, -1, 1, std::less<>{}); // == 0
# std::reduce
const std::array<int, 3> a{ 1, 2, 3 };
std::reduce(std::cbegin(a), std::cend(a)); // == 6 default binary operation is std::plus
// Using a custom binary op:
std::reduce(std::cbegin(a), std::cend(a), 1, std::multiplies<>{}); // == 6
const std::array<int, 3> b{ 1, 2, 3 };
const auto product_times_ten = [](const auto a, const auto b) { return a * b * 10; };
std::transform_reduce(std::cbegin(a), std::cend(a), std::cbegin(b), 0, std::plus<>{}, product_times_ten); // == 140
# std::inclusive_scan
const std::array<int, 3> a{ 1, 2, 3 };
std::inclusive_scan(std::cbegin(a), std::cend(a),
std::ostream_iterator<int>{ std::cout, " " }, std::plus<>{}); // 1 3 6
std::exclusive_scan(std::cbegin(a), std::cend(a),
std::ostream_iterator<int>{ std::cout, " " }, 0, std::plus<>{}); // 0 1 3
const auto times_ten = [](const auto n) { return n * 10; };
std::transform_inclusive_scan(std::cbegin(a), std::cend(a),
std::ostream_iterator<int>{ std::cout, " " }, std::plus<>{}, times_ten); // 10 30 60
std::transform_exclusive_scan(std::cbegin(a), std::cend(a),
std::ostream_iterator<int>{ std::cout, " " }, 0, std::plus<>{}, times_ten); // 0 10 30
# GCD and LCM 公倍数
const int p = 9;
const int q = 3;
std::gcd(p, q); // == 3
std::lcm(p, q); // == 9
# std::not_fn
# C++20 Coroutines
generator<int> range(int start, int end) {
while (start < end) {
co_yield start;
start++;
}
// Implicit co_return at the end of this function:
// co_return;
}
for (int n : range(0, 10)) {
std::cout << n << std::endl;
}
# concept
template <typename T>
concept unsigned_integral = integral<T> && !signed_integral<T>;
template <typename T>
concept callable = requires (T f) { f(); };
// `T` is a constrained type template parameter.
template <typename T>
requires my_concept<T>
void f(T v);
# [[likely]] and [[unlikely]] attributes
switch (n) {
case 1:
// ...
break;
[[likely]] case 2: // n == 2 is considered to be arbitrarily more
// ... // likely than any other value of n
break;
}
int random = get_random_number_between_x_and_y(0, 3);
if (random > 0) [[likely]] {
// body of if statement
// ...
}
# constexpr virtual functions
struct X1 {
virtual int f() const = 0;
};
struct X2: public X1 {
constexpr virtual int f() const { return 2; }
};
# explicit(bool)
struct foo {
// Specify non-integral types (strings, floats, etc.) require explicit construction.
template <typename T>
explicit(!std::is_integral_v<T>) foo(T) {}
};
# enum
enum class rgba_color_channel { red, green, blue, alpha };
std::string_view to_string(rgba_color_channel my_channel) {
switch (my_channel) {
using enum rgba_color_channel;
case red: return "red";
case green: return "green";
case blue: return "blue";
case alpha: return "alpha";
}
}
# constinit
const char* g() { return "dynamic initialization"; }
constexpr const char* f(bool p) { return p ? "constant initializer" : g(); }
constinit const char* c = f(true); // OK
constinit const char* d = f(false); // ERROR: `g` is not constexpr, so `d` cannot be evaluated at compile-time.
# std::span
std::span<const int, 3>{ c.cbegin(), c.cend() }
# Bit operations
std::popcount(0u); // 0
std::popcount(1u); // 1
std::popcount(0b1111'0000u); // 4
# Math constants
std::numbers::pi; // 3.14159...
std::numbers::e; // 2.71828..
# starts_with and ends_with on strings
std::string str = "foobar";
str.starts_with("foo"); // true
str.ends_with("baz"); // false
# std::midpoint
std::midpoint(1, 3); // == 2
# std::to_array
int a[] = {1, 2, 3};
std::to_array(a); // returns `std::array<int, 3>`
C++现代教程四_c++ float 转 string-CSDN博客