C++ 中文周刊 第129期

周刊项目地址

公众号

RSS https://github.com/wanghenshui/cppweeklynews/releases.atom

qq群 手机qq点击进入

欢迎投稿,推荐或自荐文章/软件/资源等

提交 issue

内容不多

感谢不语赞助


资讯

标准委员会动态/ide/编译器信息放在这里

编译器信息最新动态推荐关注hellogcc公众号 本周更新 2023-08-30 第217期

cppcon即将来临之际,c++之父BS发表重要讲话

CppCon 2023 Delivering Safe C++ – Bjarne Stroustrup

从去年开始各路人马对c++安全性的批评让BS有点坐不住了,生闷气,小甜甜变牛夫人了属于是

BS指出,当前C++的演化方向要向着安全性发展,对比存量代码相比要更安全更没有资源释放/类型安全/内存破坏等安全性问题

希望大家锐意进取,努力为更安全的C++做出自己的贡献

文章

Did you know that C++26 added Member visit

std::visit嵌入到variant里了

// C++23
std::visit(overload{
  [](int i){ std::print("i={}\n", i); },
  [](std::string s){ std::print("s={:?}\n", s); }
}, value);

// C++26
value.visit(overload{
  [](int i){ std::print("i={}\n", i); },
  [](std::string s){ std::print("s={:?}\n", s); }
});

Semi-static Conditions in Low-latency C for High Frequency Trading: Better than Branch Prediction Hints

很有意思的点子,在高频交易场景里,if分支开销太大,冷热分支也不能预测,既然不能预测,就自己动态改

代码在这里

https://github.com/maxlucuta/semi-static-conditions/

点子真的有意思

这种场景 一般来说只能经验的使用likely,或者PGO分析一下,然后加上likely

这种运行时动态改的点子,很有意思。感觉靠谱的话可以铺开

C++ Papercuts

列举了c++的缺点

const 不是默认 很坑

function能拷贝,很坑 lambda应该默认move,转移也应该move std::move_only_function赶紧快点能用

The Little Things: The Missing Performance in std::vector

老生常谈了,用户可能不想要默认构造0,能不能提供接口省掉,类似resize_for_overwrite之类的接口

我印象中folly是实现了类似的玩意

https://github.com/facebook/folly/blob/main/folly/memory/UninitializedMemoryHacks.h

template <
    typename T,
    typename = typename std::enable_if<
        std::is_trivially_destructible<T>::value &&
        !std::is_same<T, bool>::value>::type>
void resizeWithoutInitialization(std::vector<T>& v, std::size_t n) {
  if (n <= v.size()) {
    v.resize(n);
  } else {
    if (n > v.capacity()) {
      v.reserve(n);
    }
    detail::unsafeVectorSetLargerSize(v, n);
  }
}

Building C++ “Work Contracts”

设计了一种无锁的二叉堆,结合调度设计,比简单的MPMC要快

代码在这里 https://github.com/buildingcpp/network

The new static constexpr std::integral_constant idiom

std::array::size不是static的,但他明明可以是static的,只能猥琐绕过

template <typename Rng>
void algorithm(Rng const& rng) {
    constexpr auto a = Rng::size(); // error, std::array has no static size
    constexpr auto b = rng.size();  // error, not a constant expression
    constexpr auto c = std::tuple_size<Rng>::value; // okay, but ugly
}

标准库也不能把size接口直接改了,有ABI问题(我觉得改了也没啥吧这也要束手束脚不至于吧)

作者讨论通过interger_constant的新能力绕过

template <typename T, T Value>
struct integral_constant {
    constexpr T operator()() const {
        return Value;
    }
};

没错,支持operator了,那么命名一个size字段就解决了,且不用改原来的size函数


template <typename T, std::size_t N>
struct array {
    constexpr std::size_t size() const {
        return N;
    }

    static constexpr std::integral_constant<std::size_t, N> size = {};
};

彳亍

Compile-time sizes for range adaptors

承接上文,怎么适配各种各样的size?

template <typename ... Rng>
struct concat_adaptor {
	constexpr auto size() const
		requires (tc::has_size<Rng> && ...)
	{
		if constexpr ((tc::has_constexpr_size<Rng> && ...))
			return std::integral_constant<std::size_t, (tc::constexpr_size<Rng>() + ...)>{};
		else
			return std::apply([](auto const& ... base_rng) {
				return (tc::size(base_rng) + ...);
			}, base_rng_tuple);
	}
};
template <auto Fn, typename ... Rng>
constexpr auto compute_range_adaptor_size(Rng&&... rng) {
	if constexpr ((tc::has_constexpr_size<Rng> && ...)) {
		auto constexpr value = Fn(tc::constexpr_size<Rng>()...);
		return std::integral_constant<std::size_t, value>{};
	} else {
		auto const value = Fn(tc::size(std::forward<Rng>(rng))...);
		return value;
	}
}

template <typename ... Rng>
struct concat_adaptor {
	constexpr auto size() const
		requires (tc::has_size<Rng> && ...)
	{
		return std::apply([](auto const& ... base_rng) {
			return tc::compute_range_adaptor_size<[](auto const ... n) {
				return (n + ...);
			}>(base_rng...);
		}, base_rng_tuple);
	}
};

开源项目需要人手

新项目介绍/版本更新


本文永久链接

如果有疑问评论最好在上面链接到评论区里评论,这样方便搜索,微信公众号有点封闭/知乎吞评论

看到这里或许你有建议或者疑问或者指出错误,请留言评论! 多谢! 你的评论非常重要!也可以帮忙点赞收藏转发!多谢支持! 觉得写的不错那就给点吧, 在线乞讨 微信转账