从reddit/hackernews/lobsters/meetingcpp摘抄一些c++动态
周刊项目地址|在线地址 |知乎专栏 | 腾讯云+社区 |
欢迎投稿,推荐或自荐文章/软件/资源等,请提交 issue
标准委员会动态/ide/编译器信息放在这里
编译器信息最新动态推荐关注hellogcc公众号 本周更新 2022-01-12 第132期
int main() {
using namespace std;
variant<string, bool> var{"im-a-string"};
if (holds_alternative<string>(var)) {
cout << "string value is: " << get<string>(var) << endl; // GCC > 9.4
} else if (holds_alternative<bool>(var)) {
cout << "bool value is: " << get<bool>(var) << endl; // GCC <= 9.4
} else {
abort();
}
}
在旧的gcc版本会打印bool
主要原因是这个构造语意存在问题p0608r3 这个提案就是解决这个问题
#include <functional>
int main() {
{
std::function<int()> f{[]{return 42; }};
auto copy = f; // okay
auto value = f();
}
{
std::move_only_function<int()> f{[] {return 42; }};
auto copy = f; // error, call to deleted copy constructor
auto value = f(); // undefined behaviour, dandling reference
}
}
终于进c++了,叫move_only_function
concept限制的auto
void signedIntsOnly(SignedIntegral auto val) { }
void floatsOnly(std::floating_point auto fp) { }
//等价
template <SignedIntegral T>
void signedIntsOnly(T val) { }
template <std::floating_point T>
void floatsOnly(T fp) { }
比较泛化的lambda
auto fn = []<typename T>(vector<T> const& vec) {
cout << size(vec) << “, “ << vec.capacity();
};
尽可能的constexpr
#include <numeric>
constexpr int naiveSum(unsigned int n) {
auto p = new int[n];
std::iota(p, p+n, 1);
auto tmp = std::accumulate(p, p+n, 0);
delete[] p;
return tmp;
}
constexpr int smartSum(unsigned int n) {
return (1+n)*(n/2);
}
int main() {
static_assert(naiveSum(10) == smartSum(10));
return 0;
}
Using enum 简单化代码
#include <iostream>
enum class long_enum_name { hello, world, coding };
void func(long_enum_name len) {
#if defined(__cpp_using_enum) // c++20 feature testing
switch (len) {
using enum long_enum_name;
case hello: std::cout << "hello "; break;
case world: std::cout << "world "; break;
case coding: std::cout << "coding "; break;
}
#else
switch (len) {
case long_enum_name::hello: std::cout << "hello "; break;
case long_enum_name::world: std::cout << "world "; break;
case long_enum_name::coding: std::cout << "coding "; break;
}
#endif
}
enum class another_long_name { hello, breaking, code };
int main() {
using enum long_enum_name;
func(hello);
func(coding);
func(world);
// using enum another_long_name; // error: 'another_long_name::hello'
// conflicts with a previous declaration
}
复杂的NTTP (不过很少用得到)
#include <iostream>
struct Constants {
double gravityAcceleration_ { 1.0 };
constexpr double getGA() const { return gravityAcceleration_;}
};
template <Constants C>
double ComputeWeight(double mass) {
return mass * C.getGA();
}
int main() {
constexpr Constants EarthGa { 9.81 };
constexpr Constants MoonGa { 1.625 };
std::cout << ComputeWeight<EarthGa>(70.0) << '\n';
std::cout << ComputeWeight<MoonGa>(70.0) << '\n';
}
位域初始化
#include <iostream>
struct Type {
int value : 4 = 1;
int second : 4 { 2 };
};
int main() {
Type t;
std::cout << t.value << '\n';
std::cout << t.second << '\n';
}
c的字段构造
struct Point { double x; double y; };
Point p { .x = 10.0, .y = 20.0 };
nodiscard带信息
[[nodiscard("Don't call this heavy function if you don't need the result!")]]
bool Compute();
rangefor结合初始化,这也是之前提到过的range-for的缺陷问题,有了新的解决方案
//for (init; decl : expr)
for (auto& x : foo().items()) { /* .. */ } // 生命周期问题,不能这么搞
for (T thing = foo(); auto& x : thing.items()) { /* ... */ } // OK
consteval, 深度优化成立即数
consteval int sum(int a, int b) {
return a + b;
}
constexpr int sum_c(int a, int b) {
return a + b;
}
int main() {
constexpr auto c = sum(100, 100);
static_assert(c == 200);
constexpr auto val = 10;
static_assert(sum(val, val) == 2*val);
int a = 10;
int b = sum_c(a, 10); // fine with constexpr function
// int d = sum(a, 10); // error! the value of 'a' is
// not usable in a constant expression
}
看这段代码
int main() {
int isAdmin = 0;
/* } if (isAdmin) begin admins only */
__builtin_printf("You are an admin.\n");
/* end admins only { */
return 0;
}
这些特殊字符 gcc12会告警。所以后面的代码不会生效
讨论c++ repl交互的进展,一些实现,比如julia cling等等 (这玩意真的有人用吗)
有了consteval和fmtlib,代码更好写了
以前的代码
constexpr ErrorToMessage error_to_message[] = {
{ C2000, fetch_message(C2000) },
{ C2001, fetch_message(C2001) },
...
};
template <typename... Ts>
constexpr bool are_arguments_valid(ErrorNumber n) {
/* 1. fetch message
2. parse specifiers
3. check each specifier against the parameter pack Ts... */
return result;
}
template <typename... Ts>
void error(ErrorNumber n, Ts&&... ts) {
assert(are_arguments_valid<Ts...>(n));
/* do error stuff */
}
现在的代码
#include <string_view>
#include <type_traits>
// Exposition only
#define FAIL_CONSTEVAL throw
template <typename T>
struct Checker {
consteval Checker(const char* fmt) {
if (fmt != std::string_view{ "valid" }) // #1
FAIL_CONSTEVAL;
// T must be an int
if (!std::is_same_v<T, int>) // #2
FAIL_CONSTEVAL;
}
};
template <typename T>
void fmt(std::type_identity_t<Checker<T>> checked, T);
int main() {
fmt("valid", 10); // compiles
fmt("oops", 10); // fails at #1
fmt("valid", "foo"); // fails at #2
}
consteval能编译期就把不合法的使用找出来
介绍这个有量纲计算的库https://github.com/mpusz/units 编译期计算
oatpp 1.3.0发布,一个网络库
json bugfix
SObjectizer 一个actor库
toml++ 性能提升30%
toml是一种配置文件格式,ini和yaml结合的感觉。rust的cargo包管理用的就是这个格式
[library]
name = "toml++"
authors = ["Mark Gillard <mark.gillard@outlook.com.au>"]
[dependencies]
cpp = 17
暂无推荐