C++ 中文周刊 第79期

reddit/hackernews/lobsters/purecpp知乎等等摘抄一些c++动态

周刊项目地址在线地址知乎专栏 腾讯云+社区

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

可以贴在下一期草稿里 草稿链接

2022 0908 提前发了。周五有事

资讯

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

llvm 15发布了。c++20支持等等一大堆修改

lld 15 ELF changes

编译器信息最新动态推荐关注hellogcc公众号 本周更新 2022-09-07 第166期

文章

要注意协程被线程切换影响

c++23详细总结

c++20应用协程举例

std::function的分析

seastar的一些代码走读。可以看看

其实就是编译期检测接口的能力

一组协程教程

#include <ranges>

template <auto Begin, auto End, auto List>
auto slice = List
           | std::ranges::views::drop(Begin)
           | std::ranges::views::take(End);

static_assert(
  slice<1_c, 2_c, boost::mp::list<int, double, float>()>
  ==
                  boost::mp::list<double, float>());

typelist实现更简单了。恐怖

optinal的move并不会真正的move T, 让T为无效value

template <typename T>
void test(T v)
{
  optional<T> o = v;
  assert (o);     // o contains a value
  optional<T> p = std::move(o);
  assert (o);     // o still contains a value!
}

完全取决于T的move,optional会保留T的壳子。

比如unique_ptr

int * p = new int(1);
 
optional<unique_ptr<int>> op = unique_ptr<int>(p);
assert (op);
assert (op->get() == p);
 
optional<unique_ptr<int>> o2 = std::move(op);
assert (op);                   // still contains a value
assert (op->get() == nullptr); // the value is moved from
assert (o2);
assert (o2->get() == p);

unique_ptr内部会搬走,但本身是还在optional里的。这样实现更快,对于trival类型,这样优化的可以直接memcpy,更高效一些 大概实现成这个样子

template <typename Trivial>
class optional<Trivial>
{
  bool     _is_initialized;
  Trivial  _value;
 
  optional() : _is_initialized(false) {}
  // use defaulted copy and move 
};
// Second argument is a pointer to the type of std::fclose, we could also have
// written it out explicitly as std::unique_ptr<FILE, int (*)(FILE*)>.
using FilePtr = std::unique_ptr<FILE, decltype(std::fclose) *>;

// Instantiate the FILE* with the destructor we want.
FilePtr file(std::fopen(filename, "rbe"), std::fclose);

// Do stuff with the file
std::fread(buf_.data(), 1, buf_.size(), file.get());

比写个deferGuard能更干净些

using XXH3StatePtr = std::unique_ptr<XXH3_state_t, decltype(XX3_freeState) *>;
XXH3StatePtr state(XXH3_createState(), XXh3_freeState);

但这种写法的问题在于,需要判定创建失败/指针是否有效

一个简单的函数

[[nodiscard]] auto say_a_to(
    std::string_view what, std::string_view name) -> std::string {
  return std::string{what} + ", " + std::string{name} + "!";
}

say_a_to("Hi", "Kate"); // -> "Hi, Kate!"

struct {
  [[nodiscard]] auto operator()(
      std::string_view what, std::string_view name) const -> std::string {
    return std::string{what} + ", " + std::string{name} + "!";
  }
} say_b_to;

say_b_to("Hello", "Tony"); // -> "Hello, Tony!"

没啥新奇的,但是c++23支持多维数组了,所以说operator[] 也算是一种函数了

比如



struct {
  [[nodiscard]] auto operator[](
      std::string_view what, std::string_view name) const -> std::string {
    return std::string{what} + ", " + std::string{name} + "!";
  }
} say_d_to;

say_d_to["Goodbye", "Tony"]; // -> "Goodbye, Tony!"
struct {
  template <std::integral ...Ts>
  [[nodiscard]] auto operator[](Ts... ts) const noexcept {
    return (0 + ... + ts);
  }
} sum;
const auto s1 = sum[1, 2, 3]; // 6
const auto s2 = sum[];        // 0

我只能说看个乐,别这么写求求了

视频

#include <iostream>
#include <ranges>
#include <string_view>

int main() {

  // this is lazily evaluated
  auto strings = std::string_view{"Hello C++ 20"} | std::views::split(' ');

  // the result is a range of ranges
  
  for (const auto &ref : strings) {
    // C++ 20
    std::cout << '\n' << std::string_view{ref.begin(), ref.end()};
    // C++ 23
    std::cout << '\n' << std::string_view{ref};
  }
}

开源项目需要人手

工作招聘

寒冬了

华为出新手机了,但我不买,因为想把寒冬传给它

本文永久链接

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