C++ 中文周刊 第58期

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

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

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

你们说整个代码走读周会/项目分享 靠谱么。我感觉拉不到人


资讯

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

编译器信息最新动态推荐关注hellogcc公众号 2022-04-13 第145期

文章

static_assert([]<class T>{ return std::integral<T>; }.operator()<int>());

struct f { auto foo() -> void; };
static_assert([](auto t){ return requires { t.foo(); }; }(f{}));

我觉得这玩意还是不要知道的好

看个乐,挺有意思的

一些c指针的缺陷。老生常谈了属于是

复习一下chrono,c++20有个file_clock,干嘛的

windbg调试手把手教学

测了几种算法range和标准实现的表现。range下限稳定。能用range尽量用range

template<typename T>
struct Holder
{
    T value;

    template<typename... Args>
    Holder(Args&&... args) :
        value(std::forward<Args>(args)...) {}
};

template<typename U> Holder(U&&) ->
    Holder<std::remove_reference_t<U>>

省一个类型缩写 Holder(42)而不是Holder<int>42 但是问题来了,如果T的构造抛异常就完了

标记noexcept,怎么标?

    template<typename... Args>
    Holder(Args&&... args)
        noexcept(noexcept(T(std::forward<Args>(args)...))) :
        value(std::forward<Args>(args)...) {}
#include <iostream>
#include <memory>
#include <string>
#include <vector>

class Object {                                              // (2)
public:
    template <typename T>                                   // (3)
    Object(T&& obj): object(std::make_shared<Model<T>>(std::forward<T>(obj))){}
    std::string getName() const {                           // (4)
        return object->getName(); 
    }
   struct Concept {                                         // (5)
       virtual ~Concept() {}
	   	 virtual std::string getName() const = 0;
   };

   template< typename T >                                   // (6)
   struct Model : Concept {
       Model(const T& t) : object(t) {}
	   std::string getName() const override {
		   return object.getName();
	   }
     private:
       T object;
   };

   std::shared_ptr<const Concept> object;
};

void printName(std::vector<Object> vec){                    // (7)
    for (auto v: vec) std::cout << v.getName() << '\n';
}

struct Bar{
    std::string getName() const {                           // (8)
        return "Bar";
    }
};

struct Foo{
    std::string getName() const {                           // (8)
        return "Foo";
    }
};

int main(){
    std::vector<Object> vec{Object(Foo()), Object(Bar())};  // (1)
    printName(vec);
    std::cout << '\n';
}

学会这种封装思想.虽然不太会用到

constexpr unsigned long long operator""_KiB(unsigned long long int x) {
    return 1024ULL * x;
}

constexpr unsigned long long operator""_MiB(unsigned long long int x) {
    return 1024_KiB * x;
}

constexpr unsigned long long operator""_GiB(unsigned long long int x) {
    return 1024_MiB * x;
}

constexpr unsigned long long operator""_TiB(unsigned long long int x) {
    return 1024_GiB * x;
}

constexpr unsigned long long operator""_PiB(unsigned long long int x) {
    return 1024_TiB * x;
}

就是这段代码,分享给大家,增加代码可读性

作者拿这段代码到处提MR ,比如这个https://github.com/xenia-project/xenia/pull/1935/

还是fix_string

template <size_t Length>
struct fixed_string {
    char _chars[Length+1] = {}; // +1 for null terminator
};
template <size_t N>
fixed_string(const char (&arr)[N])
    -> fixed_string<N-1>;  // Drop the null terminator

template <fixed_string<6> Str>
struct foo;

foo<"Hello!"> hello;
foo<"world!"> world;
foo<"nope"> b;  // FAIL!

foo的这个6非常碍眼且不合理。c++20,可以自动推导了

template <fixed_string S>
struct ctad_foo {};
ctad_foo<"Hello"> h
ctad_foo<"user"> u;

更离谱的

template <fixed_string> // [1]
struct named_type {};

template <> // [2]
struct named_type<"integer"> { using type = int; };

template <> // [2]
struct named_type<"boolean"> { using type = bool; };

template <fixed_string S> // [3]
using named_type_t = named_type<S>::type;

named_type_t<"integer"> v = 42;
named_type_t<"boolean"> b = false;



template <fixed_string Name>
concept names_a_type = requires {
    // Require that `named_type_t<Name>` produces a valid type
    typename named_type_t<Name>;
};

static_assert(names_a_type<"integer">);
static_assert(!names_a_type<"widget">);

template <fixed_string S>
auto do_something() {
    static_assert(
        names_a_type<S>,
        "The given string must name a registered type!");
}

类型信息真正的存下来了。不过一时半会用不上

concept+ lambda

#include <concepts>

template <auto Constraint> struct requires_ {
  template <class T> requires (Constraint.template operator()<T>()) operator T();
};

#define $requires(...) requires_<[]<class _>{ return __VA_ARGS__; }>{}

template<class T>
concept fooable = requires(T t) {
  t.foo(
    $requires(std::integral<_>),
    $requires(std::same_as<short, _>)
  );
};

struct bar { void foo(); };
static_assert(not fooable<bar>);

struct foo1 { void foo(int, short); };
static_assert(fooable<foo1>);

struct foo2 { void foo(int, auto); };
static_assert(fooable<foo2>);

视频

一个编译期的json parser。代码在这里https://github.com/lefticus/json2cpp 玩出花来了

开源项目需要人手

新项目介绍/版本更新


本文永久链接

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