以下代码遇到了段错误const string&
构造函数,并以 0 退出string_view
构造函数。我知道const string&
这不是最好的方法。但根据我的理解,如果没有优化,临时string
是由构造而成const char*
,然后它的值被复制到Person
构造函数被销毁之前。构造函数对我来说看起来有效。对于查找部分,set::find (string_view)
将根据需要使用定义的 less 运算符。我没有看到这里有什么问题。我可以使用 g++-10 或 VS2022 重现该问题。
#include <set>
#include <iostream>
#include <string>
#include <string_view>
using namespace std;
struct Person{
string name;
Person(const string& s):name{s}{}
//Person(string_view s):name{s}{}
bool operator<(string_view s)const{
return name<s;
}
bool operator<(const Person& o)const{
return name<o.name;
}
};
bool operator<(string_view s,const Person& p){
return s<p.name;
}
set<Person,less<>>s;
int main(){
s.emplace("hello");
string_view hel="hel";
auto res=s.find(hel);
}
gdb 为我提供了有关崩溃的以下信息:
Program received signal SIGSEGV, Segmentation fault.
0x000000000800280c in std::char_traits<char>::copy (__s1=0x7fffff7ef1c0 "\340\361~\377\377\177", __s2=0x7fffff7ef230 "hello",
__n=<error reading variable: Cannot access memory at address 0x7fffff7eeff8>) at /usr/include/c++/10/bits/char_traits.h:401
401 copy(char_type* __s1, const char_type* __s2, size_t __n)
您的独立式operator<
递归地调用自身(并且无限地)。这是因为没有内置的<
比较一个的运算符string_view
to a string
,还有is隐式转换自string
to const Person&
.
虽然也有一个隐式转换string
to string_view
,因为函数本身的作用域/命名空间中有一个可用的转换,该转换是通过对两个操作数类型进行参数相关的查找找到的,而不是任何其他转换(感谢 Sam Varshavchik 指出了这一点)。
因此,在该函数体内,右侧操作数<
比较被转换为const Person&
,该函数因此调用自身。
要解决此问题,请将操作数转换为相同的 STL 类型;要么到 2string_view
操作数,像这样:
bool operator<(string_view s, const Person& p)
{
return s < string_view(p.name);
}
或 2string
操作数,像这样:
bool operator<(string_view s, const Person& p)
{
return string(s) < p.name;
}
注意:这不是一个特别容易发现的问题。但是,打开(完整)编译器警告可能会有所帮助。对于你的原始代码,MSVC 给了我这个:
警告 C4717:'operator
并且 clang 显示:
警告:通过此函数的所有路径都将调用自身
[-Winfinite-递归]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)