C++ 中文周刊 第60期

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

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

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

五一劳动节快乐。


资讯

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

标准委员会四月邮件列表

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

文章

手把手教你入门

忽略标题,一个协程的教程

赋值返回的是个左值,所以还能继续赋值。

int main() {
    int a = 1, b = 2, c = 3;
    (a = b) = c
    std::cout << a << b << c << std::endl; // 323
    return 0;
}

所以见到这种代码,不要惊慌,没啥毛病

class Foo;
Foo * make_Foo();
int main() {
    Foo * my_foo;
    if (my_foo = make_Foo()) //这么些能行吗?能行,就是让人难受
    {
        // ... Do things with the my_foo pointer
    }
    return 0;
}

如果你自己实现operator =,可能就有其他行为了

template<typename...Args>
auto make_t1_with_default_t2(Args&&...args)
{
    return std::pair<T1, T2>(
        std::piecewise_construct,
        std::forward_as_tuple(std::forward<Args>(args)...),
        std::make_tuple());
}

piecewise_construct相当于一个指引,能把tuple拆成一个个元素方便pair构造

forward_as_tuple简单打包把一堆参数封装成tuple

这俩玩意就这意思,省掉逐个构造/取参数的功夫

代码在这里 感兴趣的可以玩一下

这里就不展开了。我看不懂avx-512这套东西

int main() {
  char buf[50] = "y";
  for (int j = 0; j < 9; ++j) {
    std::cout << (j * 0x20000001) << std::endl;
    if (buf[0] == 'x') break;
  }
}

O3优化直接死循环

typedef int (*Function)();

static Function Do;

static int EraseAll() {
  std::cout << "Disaster Ahead" << std::endl;
  // system("rm -rf /");
  return 0;
}

void NeverCalled() {
  Do = EraseAll;  
}

int main() {
  return Do();
}

clang优化直接把Do替换成了EraseAll

// a.h
std::vector<int> FetchTwoValues(NetworkSocket& socket);

// a.cpp
std::vector<int> FetchTwoValues(NetworkSocket& socket) {
  return {socket.Fetch(), socket.Fetch()};
}

// a_test.cpp
TEST(A, Basic) {
  auto socket = MockSocket();
  std::vector<int> values = FetchTwoValues(socket);
  EXPECT_TRUE(values.size() >= 2);
  EXPECT_TRUE(0 == values[0]);
  EXPECT_TRUE(0 == values[1]);
}

如果 FetchTwoValues返回空 这个单测也可能成功,尽量用ASSERT_TRUE

all_of, any_of, none_of for_each count_if find_if find_first_of mismatch search

没啥说的

#include <chrono>
#include <format>
#include <iostream>
 
int main()
{
  namespace krn = std::chrono;
  using TwentyMins = krn::duration<int, std::ratio<20*60>>;
 
  krn::time_zone const* myTimeZone = krn::current_zone(); 
 
  krn::time_point p1 = krn::system_clock::now();
  krn::time_point p2 = myTimeZone->to_local(p1);
  krn::time_point p3 = krn::floor<TwentyMins>(p2);
 
  std::cout << std::format("{:%Y-%m-%d %H:%M}\n", p3);
}

目前c++20支持有问题,vs2022能编过

template <std::size_t N> struct fixed_string final {
  constexpr explicit(false) fixed_string(const char (&str)[N + 1]) {
    std::copy_n(str, N + 1, std::data(data));
  }

  [[nodiscard]] constexpr auto operator<=>(const fixed_string &) const = default;

  std::array<char, N + 1> data{};
};

template <std::size_t N>
fixed_string(const char (&str)[N]) -> fixed_string<N - 1>;

template<fixed_string> struct foo;

int main() {
  what_is_my_type<"Quantlab">{}; // clang: 'what_is_my_type<Quantlab>'
                                 // gcc: struct what_is_my_type<fixed_string<8>{std::array<char, 9>{"Quantlab"}}>
}

https://godbolt.org/z/fqWo5nvTa

值得一看

sort太复杂了

另外, libstdcxx libcxx也有debug mode,以前我以为只有msvc有 链接 链接 链接

fputc的接口很让人难受,返回值和写入的值不相等

介绍gcc12特性 支持c++23部分功能了,比如逗号多维数组支持

// A schema defined language and compiler beginning.
// OK OK, prelude.
enum class lang_directive {
	include,
	foreach,
	var,
	count,
};

enum class argument_requirement {
	required,
	optional,
	prohibited,
	count,
};

enum class argument_type {
	expression, // (auto v : vec)
	string, // "a string with quotes"
	name, // a single word without quotes
	count,
};

enum class compile_phase {
	preprocessor, // Parser will search for '#' + 'token'.
	compile,
	count,
};

// etc.

// I personally like to hide the descriptors in 'detail', if at all possible.
namespace detail {

struct include_descriptor {
	static constexpr auto key = lang_directive::include;
	static constexpr std::string_view token = "include";
	static constexpr auto arg_requirement = argument_requirement::required;
	static constexpr auto arg_type = argument_type::string;
	static constexpr auto phase = compile_phase::preprocessor;

	// etc.
};

struct foreach_descriptor {
	static constexpr auto key = lang_directive::foreach;
	static constexpr std::string_view token = "foreach";
	static constexpr auto arg_requirement = argument_requirement::required;
	static constexpr auto arg_type = argument_type::expression;
	static constexpr auto phase = compile_phase::compile;
};

struct var_descriptor {
	static constexpr auto key = lang_directive::var;
	static constexpr std::string_view token = "var";
	static constexpr auto arg_requirement = argument_requirement::required;
	static constexpr auto arg_type = argument_type::name;
	static constexpr auto phase = compile_phase::compile;
};


template <class Key, class... Descriptors>
struct lang_db {
	static constexpr size_t size = sizeof...(Descriptors);

	// Create compiletime or runtime accessible arrays, indexable with descriptors' key.
	static constexpr std::array<std::string_view, size> tokens{ Descriptors::token... };
	static constexpr std::array<argument_requirement, size> arg_requirements{ Descriptors::arg_requirement... };
	static constexpr std::array<argument_type, size> arg_types{ Descriptors::arg_type... };

	// Add useful helpers.
	static constexpr auto get_preprocessor_directives() {
		// Find all preprocessor directives and return std::array of their lang_directive keys.
	}

	// A LOT of static_asserts

	// etc.
};
} // namespace detail

// This is the "global" database which we'll be interrogating and interacting with.
using lang_directive_db = detail::lang_db<
	lang_directive,
	detail::include_descriptor,
	detail::foreach_descriptor,
	detail::var_descriptor
>;

开源项目需要人手

新项目介绍/版本更新


本文永久链接

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