在集合中使用结构
using struct in sets
我正在尝试制作一组集合,在 C++ 中执行此操作的正确方法是什么。我想要实现的是这样的
One = { {"DDD", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64},{"JJ", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64},
{"kk", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64}, {"LL", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64} };
我这样试过
#include <set>
#include <iostream>
#include <algorithm>
#include <cstring>
struct Config
{
const char* lbl;
const char* desc;
std::uint8_t se_2A;
std::uint8_t se_2B;
std::uint8_t se_2C;
std::uint8_t se_2D;
std::uint8_t se_2E;
std::uint8_t su_2A;
std::uint8_t su_2B;
std::uint8_t su_2C;
std::uint8_t su_2D;
std::uint8_t su_2E;
std::size_t total_size;
};
inline bool operator<(const Config& lhs, const Config& rhs)
{
return lhs < rhs;
}
int main(){
Config b1 = {"DDD", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64};
Config b2 = {"JJ", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64};
Config b3 = {"kk", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64};
Config b4 = {"LL", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64};
std::set<Config> newConfig;
std::set<std::set<Config>> One;
newConfig.insert(b1);
newConfig.insert(b2);
}
但是给我这个错误
Program received signal SIGSEGV, Segmentation fault.
0x00005555555555b9 in operator< (
lhs=<error reading variable: Cannot access memory at address 0x7fffff7feff8>, rhs=<error reading variable: Cannot access memory at address 0x7fffff7feff0>)
at main.cpp:32
执行此操作或修复错误的正确方法是什么?
您的代码的问题是您的函数无限递归地调用 operator< 函数。
要解决您的问题,您必须将 operator< 函数替换为以下代码:(如@Aconcagua 所述)
inline bool operator<(const Config& lhs, const Config& rhs)
{
return lhs.lbl < rhs.lbl &&
lhs.desc < rhs.desc &&
lhs.se_2A < rhs.se_2A &&
lhs.se_2B < rhs.se_2B &&
lhs.se_2C < rhs.se_2C &&
lhs.se_2D < rhs.se_2D &&
lhs.se_2E < rhs.se_2E &&
lhs.su_2A < rhs.su_2A &&
lhs.su_2B < rhs.su_2B &&
lhs.su_2C < rhs.su_2C &&
lhs.su_2D < rhs.su_2D &&
lhs.su_2E < rhs.su_2E &&
lhs.total_size < rhs.total_size;
}
inline bool operator<(const Config& lhs, const Config& rhs)
{
return lhs < rhs;
}
这个 operator<
调用 operator<
,它调用 operator<
,operator<
,operator<
调用...你能发现问题吗?递归是无限的,最终会溢出堆栈。
您可能打算做的是将一方的成员与另一方的成员进行比较。也就是说,让编译器完成工作更容易(需要 C++20 或更高版本):
struct Config
{
... members ...
friend auto operator<=>(const Config&, const Config&) = default;
};
比较指针与字符串的另一个问题不是比较字符串的内容。在这个简单的例子中它可能不会引起问题,但是这个翻译单元中的“Numbers”不一定与另一个翻译单元中的“Numbers”具有相同的地址。而像 char str[] = "Numbers";
这样的自动数组肯定不会有相同的地址。
要按内容比较字符串,您可以使用 std::string_view:
struct Config
{
std::string_view lbl;
std::string_view desc;
我正在尝试制作一组集合,在 C++ 中执行此操作的正确方法是什么。我想要实现的是这样的
One = { {"DDD", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64},{"JJ", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64},
{"kk", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64}, {"LL", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64} };
我这样试过
#include <set>
#include <iostream>
#include <algorithm>
#include <cstring>
struct Config
{
const char* lbl;
const char* desc;
std::uint8_t se_2A;
std::uint8_t se_2B;
std::uint8_t se_2C;
std::uint8_t se_2D;
std::uint8_t se_2E;
std::uint8_t su_2A;
std::uint8_t su_2B;
std::uint8_t su_2C;
std::uint8_t su_2D;
std::uint8_t su_2E;
std::size_t total_size;
};
inline bool operator<(const Config& lhs, const Config& rhs)
{
return lhs < rhs;
}
int main(){
Config b1 = {"DDD", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64};
Config b2 = {"JJ", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64};
Config b3 = {"kk", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64};
Config b4 = {"LL", "Numbers", 0xf, 0xf, 0xf, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 64};
std::set<Config> newConfig;
std::set<std::set<Config>> One;
newConfig.insert(b1);
newConfig.insert(b2);
}
但是给我这个错误
Program received signal SIGSEGV, Segmentation fault.
0x00005555555555b9 in operator< (
lhs=<error reading variable: Cannot access memory at address 0x7fffff7feff8>, rhs=<error reading variable: Cannot access memory at address 0x7fffff7feff0>)
at main.cpp:32
执行此操作或修复错误的正确方法是什么?
您的代码的问题是您的函数无限递归地调用 operator< 函数。
要解决您的问题,您必须将 operator< 函数替换为以下代码:(如@Aconcagua 所述)
inline bool operator<(const Config& lhs, const Config& rhs)
{
return lhs.lbl < rhs.lbl &&
lhs.desc < rhs.desc &&
lhs.se_2A < rhs.se_2A &&
lhs.se_2B < rhs.se_2B &&
lhs.se_2C < rhs.se_2C &&
lhs.se_2D < rhs.se_2D &&
lhs.se_2E < rhs.se_2E &&
lhs.su_2A < rhs.su_2A &&
lhs.su_2B < rhs.su_2B &&
lhs.su_2C < rhs.su_2C &&
lhs.su_2D < rhs.su_2D &&
lhs.su_2E < rhs.su_2E &&
lhs.total_size < rhs.total_size;
}
inline bool operator<(const Config& lhs, const Config& rhs) { return lhs < rhs; }
这个 operator<
调用 operator<
,它调用 operator<
,operator<
,operator<
调用...你能发现问题吗?递归是无限的,最终会溢出堆栈。
您可能打算做的是将一方的成员与另一方的成员进行比较。也就是说,让编译器完成工作更容易(需要 C++20 或更高版本):
struct Config
{
... members ...
friend auto operator<=>(const Config&, const Config&) = default;
};
比较指针与字符串的另一个问题不是比较字符串的内容。在这个简单的例子中它可能不会引起问题,但是这个翻译单元中的“Numbers”不一定与另一个翻译单元中的“Numbers”具有相同的地址。而像 char str[] = "Numbers";
这样的自动数组肯定不会有相同的地址。
要按内容比较字符串,您可以使用 std::string_view:
struct Config
{
std::string_view lbl;
std::string_view desc;