前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 动态新闻推送 第8期

C++ 动态新闻推送 第8期

作者头像
王很水
发布2021-08-31 17:40:01
4170
发布2021-08-31 17:40:01
举报

C++ 动态新闻推送 第8期

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

每周更新

周刊项目地址 github,在线地址

discord讨论群组 |飞书讨论群组|知乎专栏

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


资讯

编译器信息最新动态推荐关注hellogcc公众号

本周周报github直达

文章

简单概括 负数浮点数转化给无符号整型是ub

代码语言:javascript
复制
double dbl = -123.45; 
int d_cast0 = (unsigned int)dbl; //可能会被优化成0,尤其是arm平台
int d_cast = (unsigned)(int)dbl; 
// d_cast == -123
// works on both. 

参考链接2也解释了,在x86平台的汇编和arm平台汇编不同,gcc、clang、msvc都很统一地为x86-64生成了**cvttsd2si**,为arm64生成了**fcvtzu** fcvtzu导致的0

代码语言:javascript
复制
class iapi {
 public:
  virtual ~iapi() = default;
  virtual auto call() const -> int = 0;
};

struct production_api : iapi { auto call() const -> int override { return {}; } };
struct fake_api       : iapi { auto call() const -> int override { return 42; } };

struct app {
  const iapi& api;
};

int main() {
  auto production = boost::di::make_injector(
    boost::di::bind<iapi>.to<production_api>()
  );

  assert(0 == boost::di::create<app>(production).api.call());

  auto testing = boost::di::make_injector(
    std::move(production), // include all production bindings
    boost::di::bind<iapi>.to<fake_api>() [ boost::di::override ]
  );

  assert(42 == boost::di::create<app>(testing).api.call());
}

讲了一个string_view到const char* 的bug

代码语言:javascript
复制
// The Case of string_view and the Magic String 
// -- by Giovanni Dicanio

#include <stdio.h>

#include <iostream>
#include <string>
#include <string_view>

void SomeCApi(const char* name)
{
    printf("Hello, %s!\n", name);
}

void DoSomething(std::string_view name)
{
    SomeCApi(name.data());
}

int main()
{
    std::string msg = "Connie is learning C++";
    auto untilFirstSpace = msg.find(' ');

    std::string_view v{ msg.data(), untilFirstSpace };

    std::cout << "String view: " << v << '\n';

    DoSomething(v);
}

只能说,别这么写,const char*判断结尾和string_view判断结尾并不一致

想让connection只触发一次,触发然后就断开

代码语言:javascript
复制
auto singleShot = [receiver, connection](parameters) {
  QObject::disconnect(connection); // WHOPS, we don't have this yet!
  receiver->slot(parameters);
};
 
connection = connect(sender, &Sender::signal, receiver, std::move(singleShot));

这里的问题在connection在后面才生成,lambda要在前面捕获

改进方案

代码语言:javascript
复制
auto connection = std::make_unique<QMetaObject::Connection>();
auto connectionPtr = connection.get();
 
auto singleShot = [receiver, connection = std::move(connection)](parameters) {
  QObject::disconnect(*connection);
  receiver->slot(parameters);
};
 
*connectionPtr = connect(sender, &Sender::signal, receiver, std::move(singleShot))); 

难受

qt6新方案

代码语言:javascript
复制
connect(sender, &Sender::signal,
       receiver, &Receiver::slot,
       static_cast<Qt::ConnectionType>(Qt::SingleShotConnection));

提供了这个功能

那qt5咋办

这里介绍了他们的工具箱库

代码语言:javascript
复制
KDToolBox::connectSingleShot(sender, &Sender::signal, receiver, &Receiver::slot);
 
sender->causeSignalEmission(); // calls the slot, and breaks the connection
sender->causeSignalEmission(); // does NOT call the slot

第一次causeSignalEmission之后内部自然就disconnection了,也就规避了这个问题,他们的库在这里 https://github.com/KDAB/KDToolBox

直接看代码,继承string,改写char_traits,把traits的方法改写成大小写不敏感就可以了

代码语言:javascript
复制
#pragma once

#include <istream>
#include <ostream>
#include <compare>
#include <string>
#include <locale>
#include <utility>
#include <algorithm>
#include <type_traits>

inline namespace detail
{
	template<typename CharT>
	inline auto char_ieq(CharT c1, CharT c2, const std::locale& loc = std::locale())
	{
		return std::toupper(c1, loc) == std::toupper(c2, loc);
	};

	template<typename CharT>
	inline auto char_ilt(CharT c1, CharT c2, const std::locale& loc = std::locale())
	{
		return std::toupper(c1, loc) < std::toupper(c2, loc);
	};

	template<typename CharT>
	inline auto string_icmp(const CharT* s1, std::size_t n1, const CharT* s2, std::size_t n2, const std::locale& loc = std::locale())
	{
		if(std::lexicographical_compare(s1, s1 + n1, s2, s2 + n2, [&](CharT c1, CharT c2) { return char_ilt(c1, c2, loc); })) return -1;
		if(std::lexicographical_compare(s2, s2 + n2, s1, s1 + n1, [&](CharT c1, CharT c2) { return char_ilt(c1, c2, loc); })) return 1;
		return 0;
	}

	template<typename CharT>
	struct char_itraits : std::char_traits<CharT>
	{
		static auto eq(CharT c1, CharT c2)
		{
			return char_ieq(c1, c2);
		}

		static auto lt(CharT c1, CharT c2)
		{
			return char_ilt(c1, c2);
		}

		static auto compare(const CharT* s1, const CharT* s2, std::size_t n)
		{
			return string_icmp(s1, n, s2, n);
		}
	};
}

template<typename CharT, typename Alloc = std::allocator<CharT>>
class basic_istring : public std::basic_string<CharT, char_itraits<CharT>, Alloc>
{
public:
	using base = std::basic_string<CharT, char_itraits<CharT>, Alloc>;
	using base::base;

	template<typename Traits2, typename Alloc2,
	std::enable_if_t<not std::is_same_v<char_itraits<CharT>, Traits2>, void>* = nullptr>
	basic_istring(const std::basic_string<CharT, Traits2, Alloc2>& str)
	: base(str.data(), str.length()) {}

	operator auto () const
	{
		return std::basic_string<CharT>(this->data(), this->length());
	}

	template<typename Traits2, typename Alloc2>
	std::enable_if_t<not std::is_same_v<char_itraits<CharT>, Traits2>, bool>
	friend operator == (const basic_istring& lhs, std::basic_string<CharT, Traits2, Alloc2>& rhs)
	{
		return string_icmp(lhs.data(), lhs.length(), rhs.data(), rhs.length()) == 0;
	}

	template<typename Traits2, typename Alloc2>
	std::enable_if_t<not std::is_same_v<char_itraits<CharT>, Traits2>, std::strong_ordering>
	friend operator <=> (const basic_istring& lhs, std::basic_string<CharT, Traits2, Alloc2>& rhs)
	{
		return string_icmp(lhs.data(), lhs.length(), rhs.data(), rhs.length()) <=> 0;
	}

	template<typename Traits2, typename Alloc2>
	std::enable_if_t<not std::is_same_v<char_itraits<CharT>, Traits2>, bool>
	friend operator == (std::basic_string<CharT, Traits2, Alloc2>& lhs, const basic_istring& rhs)
	{
		return string_icmp(lhs.data(), lhs.length(), rhs.data(), rhs.length()) == 0;
	}

	template<typename Traits2, typename Alloc2>
	std::enable_if_t<not std::is_same_v<char_itraits<CharT>, Traits2>, std::strong_ordering>
	friend operator <=> (std::basic_string<CharT, Traits2, Alloc2>& lhs, const basic_istring& rhs)
	{
		return string_icmp(lhs.data(), lhs.length(), rhs.data(), rhs.length()) <=> 0;
	}
};

using istring = basic_istring<char>;
using iwstring = basic_istring<wchar_t>;

inline auto& operator >> (std::istream& is, istring& istr)
{
	std::string temp;
	is >> temp;
	istr = std::move(temp);
	return is;
}

inline auto& operator >> (std::wistream& wis, iwstring& iwstr)
{
	std::wstring temp;
	wis >> temp;
	iwstr = std::move(temp);
	return wis;
}

inline auto& operator << (std::ostream& os, const istring& istr)
{
	os << istr.c_str();
	return os;
}

inline auto& operator << (std::wostream& wos, const iwstring& iwstr)
{
	wos << iwstr.c_str();
	return wos;
}

inline auto operator ""_is(const char* istr, std::size_t len)
{
	return istring(istr, len);
}

inline auto operator ""_iws(const wchar_t* iwstr, std::size_t len)
{
	return iwstring(iwstr, len);
}

结论,除非spinlock有范围重叠 overlap(互相引用) 否则不会发生死锁

视频

就是检查是否以xx开头以xx结尾,string小工具

项目


看到这里或许你有建议或者疑问或者指出错误,请留言评论! 多谢! 你的评论非常重要!也可以帮忙点赞收藏转发!多谢支持!

本文永久链接

代码语言:txt
复制
     This site is open source. [Improve this page](https://github.com/wanghenshui/cppweeklynews/edit/dev/posts/008.md).
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C++ 动态新闻推送 第8期
    • 资讯
      • 编译器信息最新动态推荐关注hellogcc公众号
    • 文章
      • 视频
        • 项目
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档