从reddit/hackernews/lobsters/meetingcpp摘抄一些c++动态
周刊项目地址|在线地址 |知乎专栏 | 腾讯云+社区 |
欢迎投稿,推荐或自荐文章/软件/资源等,请提交 issue
标准委员会动态/ide/编译器信息放在这里
编译器信息最新动态推荐关注hellogcc公众号 本周更新 2022-03-09 第140期
一个async对应一个future,别共用一个future,会阻塞
using my_map = unordered_map<{
.key = type<int>, .value = type<std::string>,
.allocator = type< my_allocator< std::pair<const int, std::string > > >
}>;
注意这个用法,说实话还是挺别扭。能省几行代码
有些类型是可以拷贝但不能比较的,比如function
STL中还有哪个组件类似?
constexpr std::monostate m;
static_assert(m == m);
std::monostate按理说就是个tag类型,比较没有意义,但是这里确实可以比较,本身有value语义
再比如
constexpr std::nullopt_t n;
bool b = (n == n); // Error: does not compile!
nullopt明显没有value语义
通过把输出定向到 /dev/full
可以看到错误硬件错误,这是一个测试的好手段,可以判断如果调用了硬件接口报错是不是真的处理了错误码
$ echo "Hello World!" > /dev/full
bash: echo: write error: No space left on device
$ echo $?
1
但是c/c++是没有处理的
cat hello.c
/* Hello World in C, Ansi-style */
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
puts("Hello World!");
return EXIT_SUCCESS;
}
gcc hello.c -o hello
./hello > /dev/full
echo $?
1
strace -etrace=write ./hello > /dev/full
write(1, "Hello World!\n", 13) = -1 ENOSPC (No space left on device)
+++ exited with 0 +++
作者测试了其他语言,汇总了个表格,有些处理了,有些没处理。这里就不介绍了
用模板包装
class Car {
public:
~Car() = default;
void startEngine() {
// some implementation
}
int getTrunkSize() const {
// some implementation
}
void addFuel(double quantity) {
// some implementation
}
};
class MockCar {
public:
MOCK_METHOD(void, startEngine, (), ());
MOCK_METHOD(int, getTrunkSize, (), (const));
MOCK_METHOD(void, addFuel, (double quantity), ());
};
template <typename CarImpl>
class CarWrapper {
public:
CarWrapper(C carImpl): _carImpl(carImpl) {}
void startEngine() {
_carImpl.startEngine();
}
int getTrunkSize() const {
return _carImpl.getTrunkSize();
}
void addFuel(double quantity) {
_carImpl.addFuel();
}
private:
CarImpl _carImpl;
}
CarWrapper<MockedCar> c;
另外gmock也有新组件
TEST(CarMockTest, testStatementOrder) {
::testing::NiceMock<MockCar> c;
EXPECT_CALL(c, startEngine()).Times(1);
c.startEngine();
}
可以看googlemock/docs/CookBook.md 了解更多
经典循环展开,SWAR SIMD过程,具体的推导过程可以看原文,我这里直接贴代码了
union Pixel
{
uint8_t c[4]; // four channels: red, green, blue, alpha
uint32_t v; // full pixel value as a 32-bit integer
};
void darken(Pixel* first, Pixel* last, int darkness)
{
int lightness = 256 - darkness;
for (; first < last; ++first) {
for (int i = 0; i < 3; ++i) {
first->c[i] = (uint8_t)(first->c[i] * lightness / 256);
}
}
}
//展开
void darken(Pixel* first, Pixel* last, int darkness)
{
int lightness = 256 - darkness;
for (; first < last; ++first) {
first->c[0] = (uint8_t)(first->c[0] * lightness / 256);
first->c[1] = (uint8_t)(first->c[1] * lightness / 256);
first->c[2] = (uint8_t)(first->c[2] * lightness / 256);
}
}
//算法拆解,省掉除法, SWAR
void darken(Pixel* first, Pixel* last, int darkness)
{
int factor = darkness / 8;
for (; first < last; ++first) {
uint32_t v = first->v;
uint32_t fields = (v & 0xFF) |
((v & 0xFF00) << 2) |
((v & 0xFF0000) << 4);
fields *= factor;
fields += pack_fields(31, 31, 31);
uint32_t diff = ((fields >> 5) & 0x1F) |
((fields >> 7) & 0x1F00) |
((fields >> 9) & 0x1F0000) |
first->v = v - diff;
}
}
//SIMD改写
void darken(Pixel* first, Pixel* last, int darkness)
{
int lightness = 256 - darkness;
auto lightness128 = _mm_set_epi16(
256, lightness, lightness, lightness,
256, lightness, lightness, lightness);
void* end = last;
for (auto pixels = (__m128i*)first; pixels < end; pixels++) {
auto val = _mm_loadu_si128(pixels);
auto vlo = _mm_unpacklo_epi8(val, _mm_setzero_si128());
vlo = _mm_mullo_epi16(vlo, alpha128);
vlo = _mm_srli_epi16(vlo, 8);
auto vhi = _mm_unpackhi_epi8(val, _mm_setzero_si128());
vhi = _mm_mullo_epi16(vhi, alpha128);
vhi = _mm_srli_epi16(vhi, 8);
val = _mm_packus_epi16(vlo, vhi);
_mm_storeu_si128(pixels, val);
}
}
不太懂,windows平台的,这里标记个TODO
除了放在模板参数里,还可以这样
consteval auto as_constant(auto value) { return value;}
template<typename ... Param>
consteval decltype(auto) consteval_invoke(Param && ... param) {
return std::invoke(std::forward<Param>(param)...);
}
一般来说用不上
讲mock的