C++ 中文周刊 第47期

reddit/hackernews/lobsters/meetingcpp摘抄一些c++动态

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

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


资讯

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

编译器信息最新动态推荐关注hellogcc公众号 本周更新 20220119 第133期

标准委员会一月份邮件汇总

function_ref还在讨论中 std::execution 还在讨论中

文章

哈哈,一个有意思的bug,之前咱们也提过

void polarity_test(std::shared_ptr<Test> test)
{
    test->harness->callAndReport([test2 = std::move(test)]() mutable
    {
        test2->reverse_polarity();
        ::resume_on_main_thread([test3 = std::move(test2)]()
        {
            test3->reverse_polarity();
        });
    });
}

挂在test2 = std::move(test),move本身啥都不干,为啥会挂?

注意这个test,外面有->访问,里面有 = 访问,谁先谁后呢?c++17约定了调用顺序,所以升级c++17就解决了,保证外面的先里面的后

那c++17 之前,怎么解决?摆脱这个依赖就能修好了,比如

    auto& original_test = *test; // get this before we std::move(test)
    original_test.harness->callAndReport([test2 = std::move(test)]() ...);

再比如

    auto test_ptr = test.get(); // get this before we std::move(test)
    test_ptr->harness->callAndReport([test2 = std::move(test)]() ...);

再比如

  auto& harness = test->harness; // get this before we std::move(test)
    harness->callAndReport([test2 = std::move(test)]() ...);

一些嵌入式相关的c++使用案例,抽象gpio寄存器之类的

又是和status类似的东西,但是有个optional value,怎么说,有点像expect和optional的孩子

enum class queue_op_status {success = 0, empty, full, closed, busy};

// Returns either queue_op_status::success and value or an error status and no value
template<class T>
auto queue<T>::pop() -> status_value<queue_op_status, T>;

真的需要这个value么?

介绍三个比较常用的c++23特性

Literal suffixes for size_t uz 直接200uz,-1z,比size_t a = 200; std::ptrdiff_t b = -1;要更直观

c++20已经有

std::vector<int> v {1, 1, 2, 3, 5, 8};
for(auto i = 0u; i < v.size(); ++i)
{
   std::cout << v[i] << '\n';
}

为啥又来个uz,主要是因为容器的size()返回值是size_t,这就又造成了类型不匹配。

多维数组支持

以前只能复用operator functor

template <typename T, size_t R, size_t C>
struct matrix {
   T& operator()(size_t const r, size_t const c) noexcept {
      return data_[r * C + c];
   }
   T const & operator()(size_t const r, size_t const c) const noexcept {
      return data_[r * C + c];
   }
   static constexpr size_t Rows = R;
   static constexpr size_t Columns = C;
private:
   std::array<T, R* C> data_;
};
int main() {
   matrix<int, 2, 3> m;
   for (size_t i = 0; i < m.Rows; ++i) {
      for (size_t j = 0; j < m.Columns; ++j) {
         m(i, j) = i * m.Columns + (j + 1);
      }
   }
   for (size_t i = 0; i < m.Rows; ++i) {
      for (size_t j = 0; j < m.Columns; ++j) {
         std::cout << m(i, j) << ' ';
      }
      std::cout << '\n';
   }
}

c++23可以这样

T& operator[](size_t const r, size_t const c) noexcept {
   return data_[r * C + c];
}
T const & operator[](size_t const r, size_t const c) const noexcept {
   return data_[r * C + c];
}

int main() {
   matrix<int, 3, 2> m;
   for (size_t i = 0; i < m.Rows; ++i) {
      for (size_t j = 0; j < m.Columns; ++j) {
         m[i, j] = i * m.Columns + (j + 1);
      }
   }

   for (size_t i = 0; i < m.Rows; ++i) {
      for (size_t j = 0; j < m.Columns; ++j) {
         std::cout << m[i, j] << ' ';
      }
      std::cout << '\n';
   }    
}

可读性更高了

contains() string string_view方法。挺离谱这个一直没有,要用find

视频

小对象尽量传值别用引用指针,或者把c的restrict用起来,一些坑,比如需要用std::ref的场景,需要用decay_copy的场景(c++23 auto(x)可以有类似的效果)

#include <iostream>

template<class T> 
constexpr std::decay_t<T>
decay_copy(T&& v)
    noexcept(std::is_nothrow_convertible_v<T, std::decay_t<T>>)           // exposition only
{
     return std::forward<T>(v);
}

int main() {
  std::vector<int> v1{1, 2, 1, 1, 1};
  auto v2 = v1;
  v1.erase(
      std::remove(begin(v1), end(v1), *std::max_element(begin(v1), end(v1))),
      v1.end());
  v2.erase(std::remove(
               begin(v2), end(v2),
               decay_copy(*std::max_element(begin(v2), end(v2)))),
           v2.end());
  std::cout << "v1.size()=" << v1.size() << std::endl 
            << "v2.size()=" << v2.size()
            << std::endl;
  return 0;
}

开源项目需要人手

新项目介绍/版本更新

原理就是初始化N个对象,记住第一个地址和对象大小/偏移,来自己定位。挺闲的这个玩意

工作招聘


本文永久链接

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