c++一个基础问题

2021-06-11 22:18:07 +08:00
 zxCoder
std::string str=std::string("5");
std::regex_search(str,res,std::regex(R"(-?(\d+)|(\d+\.\d+))"));

上面这个是对的,下面这个编译报错,ide 提示我说找不到匹配的函数

std::regex_search(std::string("5"),res,std::regex(R"(-?(\d+)|(\d+\.\d+))"));

我不知道如何搜索相关知识点,根据我有限的认知没理解这两个的区别...

2542 次点击
所在节点    C++
14 条回复
BrettD
2021-06-11 22:22:05 +08:00
cppreference.com 查标准库函数参考资料
BrettD
2021-06-11 22:23:58 +08:00
https://en.cppreference.com/w/cpp/regex/regex_search
第一个能编译通过是使用了 string 引用的重载形式
BiteTheDust
2021-06-11 22:59:11 +08:00
template<typename _Ch_traits, typename _Ch_alloc,
typename _Alloc, typename _Ch_type,
typename _Rx_traits>
bool
regex_search(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>&&,
match_results<typename basic_string<_Ch_type,
_Ch_traits, _Ch_alloc>::const_iterator, _Alloc>&,
const basic_regex<_Ch_type, _Rx_traits>&,
regex_constants::match_flag_type
= regex_constants::match_default) = delete;



在你的代码中,上面的是左值,下面的是右值,而右值在源码里被 delete 了,所以找不到。
jasonkayzk
2021-06-12 09:25:36 +08:00
一个是左值,一个是右值,怎么能混为一谈;
zxCoder
2021-06-12 09:47:55 +08:00
@jasonkayzk 这个内容还没学到
codehz
2021-06-12 12:01:59 +08:00
其实正常来说 const &是应该能匹配到任何值型别的,但是我由于这里显式删除了&&,导致它就没法匹配上了
yazoox
2021-06-12 13:46:14 +08:00
@codehz 请教一下,这里“哪儿”看出来“显式删除了&&”?看不懂……
shrikextl
2021-06-12 16:50:17 +08:00
@yazoox 后面的 = delete
kilasuelika
2021-06-12 19:10:58 +08:00
@zxCoder 左值就是表示可以把其它值赋值给它,可以出现在等号左边,右值只能出现在等号右边。
最简单的例子 x=5,x 是左值,可以让 x 等于其它值。5 是右值,不能把其它值给 5 。
zxCoder
2021-06-12 19:18:49 +08:00
@kilasuelika 简单的例子能理解。。不过结合到具体情况就有点难懂,似乎只有 c++有这种左值右值的说法?
codehz
2021-06-12 19:57:24 +08:00
新版值型别复杂了很多,建议按 https://zh.cppreference.com/w/cpp/language/value_category
不过这里只需要区分引用初始化就可以了,所以应该看
https://zh.cppreference.com/w/cpp/language/reference_initialization
但是为了解释这里&&被干掉的原因,需要看
https://zh.cppreference.com/w/cpp/language/overload_resolution
GeruzoniAnsasu
2021-06-14 05:10:38 +08:00
继续摘原文:

7) The overload (3) is prohibited from accepting temporary strings, otherwise this function populates match_results m with string iterators that become invalid immediately.
regex_search will successfully match any subsequence of the given sequence, whereas std::regex_match will only return true if the regular expression matches the entire sequence.

匹配结果是传入参数上的迭代器,所以不禁用右值引用会使迭代器尝试迭代已消失的临时对象从而引发访问违例


并不是 c++ 才有左右值,这本来应该是个 PL 概念,c++需要区分得尤为清楚的原因是它的内存模型和抽象实现方式与大多数其它主流语言不一样,无法依赖 gc 来管理对象的内存,所以需要严格划分哪些是持久对象,哪些是可转移到持久对象上的临时对象,哪些是正在消失的临时对象,哪些是纯值可以省略构造临时对象的对象……

一般写代码分清楚了也没用,到时候还是会收束到查 cppreference 的历史线……
GeruzoniAnsasu
2021-06-14 05:19:50 +08:00
hhh 其实我刚才去复习值类别的时候在想右值引用是包含了 xvalue (会消失的临时对象)和 prvalue (纯值,比如数字、字面量)的,regex_search 这个函数不能接受传入临时对象我可以理解,但应该可以接受字符串字面量才对,比如 regex_search("something", ...

编译器是完全能做到让字面量持久化的

然后一想,c++好像并没有办法 trait 出一个 prvalue,然后再一看,第二个重载就是 const char*。 好嘛原来根本不需要 trait 出 prvalue 型,标准库已经考虑全了
hxndg
2021-08-19 23:59:00 +08:00
临时变量这个应该纯属规定了,你要是找理由实际上可以说是
1 这就是 C++哲学
2 临时变量不会被修改,你不会声明一个临时变量,然后修改它的值
3 因为没办法被捕捉,所以你也没办法去修改它

但是我个人觉得这个规定存在也挺好,见过几个对临时变量操作导致的 BUG,所以理论上如果写一些库最好也禁止对右值的操作比较好。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/783016

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX