C++ 中文周刊 第70期

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

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

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

2022 07 11

资讯

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

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

文章

template<class T> concept fooable = requires(T t) { t.foo; };
template<class T> concept barable = requires(T t) { t.bar; };

template<class T> constexpr auto foobar = "unknown"sv;
template<fooable T> constexpr auto foobar<T> = "foo"sv;
template<barable T> constexpr auto foobar<T> = "bar"sv;

struct none {};
static_assert("unknown"sv == foobar<none>);
struct f { int foo; };
static_assert("foo"sv == foobar<f>);
struct b { int bar; };
static_assert("bar"sv == foobar<b>)
int divide1(int a, int b) {
    if (b != 0) {
        return a / b;
    } else {
        throw std::runtime_error("div by zero");
    }
}

void throw_error() {
    throw std::runtime_error("div by zero");
}
int divide2(int a, int b) {
    if (b != 0) {
        return a / b;
    } else {
        throw_error();
    }
}

两个区别在于 throw = noreturn 你用函数封装,分析不出这个函数是否是noreturn的行为。可以给这个函数标记noreturn

做编译器的,介绍他的这个功能背景和实现

讲windows的。看不懂

#ifndef _GLIBCXX17_INLINE
# if __cplusplus > 201402L
#  define _GLIBCXX17_INLINE inline
# else
#  define _GLIBCXX17_INLINE
# endif
#endif

_GLIBCXX17_INLINE constexpr
  piecewise_construct_t piecewise_construct =
    piecewise_construct_t();

inline constexpr有助于节省二进制

一个报错

error C2440: '<function-style-cast>': cannot convert from 'initializer list' to 'winrt::Windows::Web::Http::HttpFormUrlEncodedContent'
message : No constructor could take the source type, or constructor overload resolution was ambiguous

构造函数的参数不可见的,导致推导不出调用哪个构造函数

#include <iostream>
#include <string>
#include <boost/variant.hpp>

struct VariantA {
    std::string url;
    std::string port;
    std::string token;
};

struct VariantB {
    std::string username;
    std::string password;
};

class Parameters {
public:
    Parameters(VariantA a) : params(a) {}
    Parameters(VariantB b) : params(b) {}
    boost::variant<VariantA, VariantB> get() const {return params;}
private:
    boost::variant<VariantA, VariantB> params;
};

Parameters makeParams(VariantA a) {
    return {a};
}

void print(unsigned char* p) {
    std::cout << p << '\n';
}

void foo(const Parameters& p) {
     const auto& va = boost::get<VariantA>(
      p.get()
    );
     print((unsigned char*)va.url.c_str());
     print((unsigned char*)va.port.c_str());
     print((unsigned char*)va.token.c_str());
}

int main() {
    VariantA a;
    a.url = "url";
    a.port = "port";
    a.token = "token";
  
    auto p = makeParams(a);
  
    foo(p);
}

哪里有问题? 这里 const auto& va = boost::get<VariantA>(p.get());

经典错误。右值的右值还能用吗。不能。这个问题在range for中也有 就是生命周期问题。右值的生命周期被意外的延长了,使用 clang的-Wdangling-gsl帮你查

视频

cppnow视频开始放流了。这里更新个

几个优化点,二分查找要尽可能的cache friendly,这样并不慢。之前也提到过b-tree的二分查找不慢,因为cache热

然后讲了robin hood hashtable的实现,介绍SIMD with a register原理 SWAR,说了一大堆hash map和 trie结合的设计,以及swar应用。代码没有开源。看了个寂寞

开源项目需要人手

新项目介绍/版本更新

工作招聘

有没有需要看大门的


本文永久链接

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