layout | title |
---|---|
post |
第144期 |
公众号
qq群 点击进入
RSS https://github.com/wanghenshui/cppweeklynews/releases.atom
欢迎投稿,推荐或自荐文章/软件/资源等
请提交 issue 或评论区留言
大家新年快乐
群友讨论了一个场景
#include <vector>
#include <memory_resource>
#include <iostream>
int main() {
std::pmr::monotonic_buffer_resource pool{10000};
std::pmr::synchronized_pool_resource pool2;
std::pmr::vector<int> vec(5, &pool);
static_assert(!std::allocator_traits<std::pmr::vector<int>::allocator_type>::propagate_on_container_swap::value, "is true");
std::pmr::vector<int> vec2(4, &pool2);
std::cout << vec.data() << " " << vec2.data() << std::endl;
vec2.swap(vec);
std::cout << vec.data() << " " << vec2.data() << std::endl;
return 0;
}
// 0x557469f1c500 0x557469f1eea0
// 0x557469f1eea0 0x557469f1c500
地址居然是可交换的,显然这是UB
std::allocator_traits<allocator_type>::propagate_on_container_swap::value
If std::allocator_traits<allocator_type>::propagate_on_container_swap::value is true, then the allocators are exchanged using an unqualified call to non-member swap. Otherwise, they are not swapped (and if get_allocator() != other.get_allocator(), the behavior is undefined).
标准委员会动态/ide/编译器信息放在这里
编译器信息最新动态推荐关注hellogcc公众号 本周更新 2023-12-27 第234期
- 1. 基于 c++ executions的异步实现 - 从理论到实践
- 基于 c++ executions的异步实现 - libunifex的使用与实现概述
- 3. exectuions 依赖的管道实现 - 在C++中实现LINQ
- 4. executions 依赖的定制机制 - 揭秘 cpo与tag_invoke!
- 5. 基于 c++ executions的异步实现 - libunifex中的concepts详解
- 6. 基于 c++ executions的异步实现 - strutured concurrency实现解析
- 7. 基于 c++ executions的异步实现 - libunifex的scheduler实现
沈芳的一波execution文章,写得不错,学吧,都是知识
还是协程,再看一遍
tag_invoke疑似有点太泛型了,作者觉得还是rust traits直观,提出了个traits object的概念
看代码 https://godbolt.org/z/Ge43cWfn8
#include <type_traits>
constexpr inline struct {
constexpr auto eq(auto rhs, auto lhs) const {return rhs == lhs;}
constexpr auto ne(auto rhs, auto lhs) const {return !eq(lhs, rhs);}
} partial_eq_default;
template<class T>
constexpr inline auto partial_eq = partial_eq_default;
template<>
constexpr inline auto partial_eq<double> = std::false_type{};
constexpr bool f(auto lhs, auto rhs) {
return partial_eq<decltype(lhs)>.eq(lhs, rhs);
}
// bool g(double lhs, double rhs) {
// auto& op = partial_eq<decltype(lhs)>;
// return op.ne(lhs, rhs);
// }
constexpr bool g(int lhs, int rhs) {
auto& op = partial_eq<int>;
return op.ne(lhs, rhs);
}
static_assert(f('a', 'a'));
static_assert(!f('a', 'b'));
static_assert(g('a', 'b'));
int main() {
bool b1 = f(1,2);
bool b2 = g(1,2);
return 0;
}
挺好的。之前132期提到定制log就是类似的技术
namespace logging {
namespace null {
struct config {
struct {
template <level L, typename... Ts>
// NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
constexpr auto log(Ts &&...) const noexcept -> void {}
} logger;
};
} // namespace null
template <typename...> inline auto config = null::config{};
template <level L, typename... Ts, typename... TArgs>
static auto log(TArgs &&...args) -> void {
auto &cfg = config<Ts...>;
cfg.logger.template log<L>(std::forward<TArgs>(args)...);
}
}
#include <meta>
int main() {
struct foo {};
std::cout << std::meta::name_of(^foo); // prints foo
}
没啥说的
众所周知,static局部对象只初始化一次
struct ExpensiveInitialization {
ExpensiveInitialization() noexcept;
void DoWork() noexcept;
};
void DoWork() noexcept {
static ExpensiveInitialization expensive;
expensive.DoWork();
}
但如果DoWork或者ExpensiveInitialization变成模版函数,是不是意味着 static每个函数都构建一次?破坏了语义?
作者提出了一种模版特化校验的方法
#include <type_traits>
template<bool const* p, typename SLOC>
struct assert_single_instantiation final {
friend consteval std::integral_constant<bool const*, p> detect_multiple_instances(SLOC) {
return {};
}
};
#define ASSERT_SINGLE_INSTANTIATION \
{ \
static constexpr bool _b = false; \
[](auto sloc) noexcept { \
[[maybe_unused]] assert_single_instantiation<&_b, decltype(sloc)> _; \
}(std::integral_constant<int, __COUNTER__>()); \
}
#define singleton_static ASSERT_SINGLE_INSTANTIATION; static
struct ExpensiveInitialization {
ExpensiveInitialization() noexcept;
void DoWork() noexcept;
};
void DoWork() noexcept {
singleton_static ExpensiveInitialization expensive;
expensive.DoWork();
}
没有任何额外开销 https://godbolt.org/z/hcEWeqf6P
就是我没看明白怎么用的
- How to allocate address space with a custom alignment or in a custom address region
- What does it mean when the compiler says that it can’t convert something to itself?
一段会泄漏内存的抽象代码
#include <vector>
struct V : std::vector<V> {}
int main() {
V v;
v.emplace_back();
v.swap(v.front());
}
非常幽默
众所周知,vector是三个指针,begin end storend三部分,swap交换自己的时候,这三个指针怎么赋值?
当然,写成c就更容易懂了 (感谢群友@只看封面)
V相当于 class V { V* data;}
看不太懂,也没放源代码。感觉是用intel的jmp汇编和goto搞跳转
- asteria 一个脚本语言,可嵌入,长期找人,希望胖友们帮帮忙,也可以加群753302367和作者对线
- Unilang deepin的一个通用编程语言,点子有点意思,也缺人,感兴趣的可以github讨论区或者deepin论坛看一看。这里也挂着长期推荐了
- gcc-mcf 懂的都懂
- https://github.com/PickNikRobotics/data_tamer 一个时间采集数据结构,类似bvar
- https://github.com/Futureblur/magnet 又一个包管理器
- https://github.com/proh14/ptext 一个类似nano的编辑器
- https://github.com/germandiagogomez/words-counter-benchmarks-game 一个word count各种实现压测比较
- https://github.com/tdanyluk/bgi2 BGI2 (Beginners' Graphic Interface 2) library 看不懂是啥
- https://github.com/spacewalk01/nanosam-cpp C++ TensorRT Implementation of NanoSAM 不知道是啥
- https://github.com/ChristianPanov/lwlog 又一个日志库
字节的音视频团队,主要负责剪映上的音视频/非线性编辑相关工作,业务前景也比较好,目前有三个方向的岗位
- 桌面端音视频研发 https://job.toutiao.com/s/i8enPrw5
- 多端音视频引擎研发 https://job.toutiao.com/s/i8enr7Es
- C++工程基础架构研发 https://job.toutiao.com/s/i8enjTHT
base北上广深杭都可以,薪资open,有兴趣的同学可以通过链接投递
大家新年快乐,祝大家健康!散会!
如果有疑问评论最好在上面链接到评论区里评论,这样方便搜索,微信公众号有点封闭/知乎吞评论