前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 中文周刊 2024-10-22 第169期

C++ 中文周刊 2024-10-22 第169期

作者头像
王很水
发布2024-10-22 16:12:37
650
发布2024-10-22 16:12:37
举报
文章被收录于专栏:C++ 动态新闻推送

资讯

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

编译器信息最新动态推荐关注hellogcc公众号 本周更新 2024-10-16 第276期

十月邮件列表 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/#mailing2024-10

让status更好的move,避免使用误用

一个pr观察 github.com/apache/arrow/pull/44477

起因

代码语言:javascript
复制
if (auto&& status = functionReturningArrowResult().status(); status.ok())
  return 0;
return -1;

显然status是调用出现问题,status()返回的不是值而是const Status& ,而函数执行完了,所以这个Status已经析构,UB

这个问题和range for loop中的悬垂引用问题一样。

这里引入了一个解决办法,支持多种status()方法

代码语言:javascript
复制
constexpr const Status& status() const& { return status_; }
Status status() && { return status_; }

status() 支持两种 分别是普通引用和万能引用,及时的把值复制出来

这种场景我以前也介绍过,但是不单单这么简单,这个PR还改动了别的地方

代码语言:javascript
复制
  /// Helper method for implementing Status returning functions in terms of semantically
  /// equivalent Result returning functions. For example:
  ///
  /// Status GetInt(int *out) { return GetInt().Value(out); }
  template <typename U, typename E = typename std::enable_if<
                            std::is_constructible<U, T>::value>::type>
  Status Value(U* out) && {
    if (!ok()) {
-      return status();
+     return std::move(*this).status();
    }
    *out = U(MoveValueUnsafe());
    return Status::OK();
  }
代码语言:javascript
复制

这算是一个挺妙的改动,std::move(*this)强制右值,这样就会调用status() && 从而帮助编译器优化潜在的悬垂场景

这种增加&&方法不是简单的增加一个就完了,还有其余的影响也需要覆盖到。这个PR算是见到一个思路

文章

Detect C++ Memory Leaks with ALSan: Attachable Leak Sanitizer - Bojun Seo - C++Now 2024

https://www.youtube.com/watch?v=9f5hd-8suVE&ab_channel=CppNow

觉得 -fsanitize=leak[1] 需要preload重跑

麻烦,自己写了个基于ebpf的

What is faster: vec.emplace_back(x) or vec[x] ?

https://johnnysswlab.com/what-is-faster-vec-emplace_backx-or-vecx/

emplace_back没有向量化优势

Iterating through matched characters in modern C++

https://lemire.me/blog/2024/10/06/iterating-through-matched-characters-in-modern-c-viewsfilter-and-coroutine/

查找,代码

代码语言:javascript
复制
std::string data = load_file_content("data.html");
std::string_view targets = "<&\r\0";
auto start = data.begin();
auto end = data.end();
while (start != end) {
  start = std::find_first_of(start, end, targets.begin(),
       targets.end());
  if (start != end) { 
    /* you are pointing at start */
  }
}
代码语言:javascript
复制

也可以这样写

代码语言:javascript
复制
size_t location = 0;
while ((location = data.find_first_of(targets, location)) !=
  std::string::npos) {
  // matched character at data[location]
  location++;
}

还可以用range

代码语言:javascript
复制
auto matched_characters =
  data | std::views::filter([](char c) {
    return c == '<' | c == '&' | c == '\r' | c == '\0';
});
for (const char &c : matched_characters) {
  /* you hold a reference to a matched character */
};
代码语言:javascript
复制

甚至可以这样写

代码语言:javascript
复制
auto target_finder = [](auto& data,
    auto& targets) -> std::generator<const char *> {
  auto start = data.begin();
  auto end = data.end();
  while (start != end) {
    start = std::find_first_of(start, end, targets.begin(),
                               targets.end());
      if (start == end) {
        co_return;
      }
      co_yield start;
      start++;
    }
};

for (auto match : target_finder(data, targets)) {
   /* match is a matched character*/
};
代码语言:javascript
复制

性能比较差还是算了

A Two Dimensional Low Discrepancy Shuffle Iterator (+Random Access & Inversion)

https://blog.demofox.org/2024/10/04/a-two-dimensional-low-discrepancy-shuffle-iterator-random-access-inversion/

Scaling Points In a Specific Direction

https://blog.demofox.org/2024/10/15/scaling-points-in-a-specific-direction/

看不懂,图形学的

Why don’t compilers warn for const T f()?

https://quuxplusone.github.io/blog/2024/10/07/wqual-class-return-type/

告警太多,干脆忽略,反正没用

Replace strings by views when you can

https://lemire.me/blog/2024/09/09/replace-stdstring-by-stdstring_view-when-you-can/

view传值更省,const string&潜在拷贝风险/指针不能彻底优化

他的这个例子是tring table vs 巨大array + stringview维护,stringview占优势。代码就不贴了

Reflection in C++26

https://www.modernescpp.com/index.php/reflection-in-c26/

直接贴代码

简单例子

代码语言:javascript
复制
#include <iostream>
#include <cassert>
#include <concepts>

int main() {
    constexpr auto r = ^int;
    typename[:r:] x = 42;       // Same as: int x = 42;
    typename[:^char:] c = '*';  // Same as: char c = '*';

    static_assert(std::same_as<decltype(x), int>);
    static_assert(std::same_as<decltype(c), char>);
    assert(x == 42);
    assert(c == '*');
}
代码语言:javascript
复制

使用^拿到类型 std::meta::info,使用[: :] 使用类型

一个enum转string例子

代码语言:javascript
复制
#include <iostream>
#include <experimental/meta>
#include <string>
#include <type_traits>


template<typename E>
  requires std::is_enum_v<E>                      // (1)
constexpr std::string enum_to_string(E value) {
  std::string result = "<unnamed>";
  [:expand(std::meta::enumerators_of(^E)):] >>    // (2)
  [&]<auto e>{
    if (value == [:e:]) {
      result = std::meta::identifier_of(e);       // (3)
    }
  };
  return result;
}

template <typename E>
  requires std::is_enum_v<E>                           
constexpr std::optional<E> string_to_enum(std::string_view name) {
  template for (constexpr auto e : std::meta::enumerators_of(^E)) {
    if (name == std::meta::identifier_of(e)) {                     
      return [:e:];
    }
  }

  return std::nullopt;
}

int main() {
    enum Color { red, green, blue };
    std::cout << "enum_to_string(Color::red): " << enum_to_string(Color::red) << '\n';
}
代码语言:javascript
复制

(2) 不好懂,你就当一种特殊语法好了,执行指定lambda

内置的metafunction非常多 这里就不列出来了,太长了

感知字段

代码语言:javascript
复制

#include <experimental/meta>
#include <iostream>

struct Base { 
    int i{}; 
    void inc(int& j){ j++; }
};

consteval auto number(int n) {
  //return std::meta::nonstatic_data_members_of(^Base)[n];
  return std::meta::members_of(^Base)[n];
}


consteval auto named(std::string_view name) {
  for (std::meta::info field : std::meta::members_of(^Base)) {
    if (std::meta::has_identifier(field) && std::meta::identifier_of(field) == name)
      return field;
  } 
  return std::meta::info{};
}


int main() { 
  Base base;
  base.[:number(0):] = 1;  
  // base.[:member_number(10):] = 1;  Error
  std::cout << "base.i= " << base.i << '\n';
  base.[:number(1):](base.i);
  std::cout << "base.i= " << base.i << '\n';

  std::cout << '\n';
 
  base.[:named("i"):] = 3;
  std::cout << "base.i= " << base.i << '\n';
  base.[:named("inc"):](base.i);
  std::cout << "base.i= " << base.i << '\n';
}
代码语言:javascript
复制

感知布局

代码语言:javascript
复制
#include <experimental/meta>
#include <iostream>
#include <utility>
#include <vector>
#include <array>

struct member_descriptor
{
  std::size_t offset;
  std::size_t size;
  bool operator==(member_descriptor const&) const = default;
};

// returns std::array<member_descriptor, N> The company's biggest funding.
template <typename S>
consteval auto get_layout() {
  constexpr size_t N = []() consteval {
    return nonstatic_data_members_of(^S).size();
  }();

  std::array<member_descriptor, N> layout;
  [: expand(nonstatic_data_members_of(^S)) :] >> [&, i=0]<auto e>() mutable {
    layout[i] = {.offset=offset_of(e), .size=size_of(e)};
    ++i;
  };
  return layout;
}

struct X
{
    char a;
    int b;
    double c;
};

int main() {

    std::cout << '\n';
    
    constexpr auto layout = get_layout<X>();

    std::cout << "Layout of struct X:\n";
    for (const auto& member : layout) {
        std::cout << "Offset: " << member.offset << ", Size: " << member.size << '\n';
    }

    std::cout << '\n';

}
代码语言:javascript
复制


潜力还是非常大的

A popular but wrong way to convert a string to uppercase or lowercase '

https://devblogs.microsoft.com/oldnewthing/20241007-00/?p=110345

对于std::wstring tolower toupper不能用,可能得用icu库u_strToUpper / u_strToLower

C++ 协程 - 协程理论 https://zhuanlan.zhihu.com/p/2095237709
C++ 协程 - 任务 https://zhuanlan.zhihu.com/p/2117165235

概念介绍的不错

C++ String Conversion: Exploring std::from_chars in C++17 to C++26

https://www.cppstories.com/2018/12/fromchars/

新版本功能进化了,支持浮点数,让from_chars_result支持bool更好用

代码语言:javascript
复制
#include <charconv> // from_char, to_char
#include <string>
#include <iostream>

int main() {
    const std::string str { "16.78" };
    double value = 0;
    const auto format = std::chars_format::general;
    const auto res = std::from_chars(str.data(), 
                                 str.data() + str.size(), 
                                 value, 
                                 format);

    if (res.ec == std::errc()) {
        std::cout << "value: " << value 
                  << ", distance: " << res.ptr - str.data() << '\n';
    } else if (res.ec == std::errc::invalid_argument) {
        std::cout << "invalid argument!\n";
    } else if (res.ec == std::errc::result_out_of_range) {
        std::cout << "out of range! res.ptr distance: " 
                  << res.ptr - str.data() << '\n';
    }
}
代码语言:javascript
复制

c++26可以直接 if (res) { ... }

互动环节

我都一个月没更新了也没人鸟,感觉没有互动好无聊,大家的互动非常重要,点赞+评论过20,下周必更新

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CPP每周推送 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 资讯
  • 文章
    • Detect C++ Memory Leaks with ALSan: Attachable Leak Sanitizer - Bojun Seo - C++Now 2024
      • What is faster: vec.emplace_back(x) or vec[x] ?
        • Iterating through matched characters in modern C++
          • A Two Dimensional Low Discrepancy Shuffle Iterator (+Random Access & Inversion)
            • Scaling Points In a Specific Direction
              • Why don’t compilers warn for const T f()?
                • Replace strings by views when you can
                  • Reflection in C++26
                    • A popular but wrong way to convert a string to uppercase or lowercase '
                      • C++ 协程 - 协程理论 https://zhuanlan.zhihu.com/p/2095237709
                        • C++ 协程 - 任务 https://zhuanlan.zhihu.com/p/2117165235
                          • C++ String Conversion: Exploring std::from_chars in C++17 to C++26
                          • 互动环节
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档