如何比较POD类型的对象

BЈо*_*вић 14 c++ comparison pod

这个例子:

#include <iostream>
#include <cstring>

struct A
{
    int  a;
    bool b;
};

bool foo( const A a1, const A a2 )
{
    return ( 0 == std::memcmp( &a1, &a2, sizeof( A ) ) );
}

int main()
{
    A a1 = A();
    a1.a = 5;a1.b = true;
    A a2 = A();
    a2.a = 5;a2.b = true;

    std::cout<<std::boolalpha << foo( a1, a2 ) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

false由于填充,将产生.

我没有访问该foo功能,我无法改变比较的方式.

假设bool占用1个字节(在我的系统上也是如此),如果我将其更改struct A为:

struct A
{
  int a;
  bool b;
  char dummy[3];
};
Run Code Online (Sandbox Code Playgroud)

然后它在我的系统上工作正常(输出是true).

还有什么我可以做的来解决上述问题(得到true输出)?

Naw*_*waz 17

由于结构中的填充,第一个不起作用.填充对于两个对象具有不同的位模式.

如果在使用之前memset用于设置对象中的所有位,那么它将起作用:

A a1;
std::memset(&a1, 0, sizeof(A));
a1.a = 5;a1.b = true;

A a2;
std::memset(&a2, 0, sizeof(A));
a2.a = 5;a2.b = true;
Run Code Online (Sandbox Code Playgroud)

在线演示:


顺便说一句,你可以写operator<, operator== 等等,对荚也.

  • @VJo:没有.它不相同`A a1 = A()`只初始化成员,而不是填充.也就是说,`A a1 = A()`相当于`A a1; memset(&a1.a,0,sizeof(a1.a)); memset(&a1.b,0,sizeof(a1.b));`.剩余的`(sizeof(A) - sizeof(a1.a) - sizeof(a1.b))`字节保持原样,包含垃圾. (2认同)

Den*_*kov 5

由于C ++ 11我们可以用简单的POD比较的元组(元组使用逐一比较了><>=<=运营商,对更多的信息:https://en.cppreference.com/w/cpp/utility/tuple/operator_cmp):

#include <iostream>
#include <tuple>

struct Point {
    int x;
    int y;
    int z;    
};


auto pointToTuple(const Point& p) {
    return std::make_tuple(p.x, p.y, p.z);
}

bool operator==(const Point& lhs, const Point& rhs ) {
    return pointToTuple(lhs) == pointToTuple(rhs);
}

bool operator<(const Point& lhs, const Point& rhs ) {
    return pointToTuple(lhs) < pointToTuple(rhs);
}

int main()
{

    Point a{1, 2, 3};
    Point b{1, 2, 3};
    Point c{2, 2, 2};

    std::cout << (pointToTuple(a) == pointToTuple(b) ? "true" : "false") << "\n"; //true
    std::cout << (pointToTuple(a) == pointToTuple(c) ? "true" : "false") << "\n"; //false

    std::cout << (a == b ? "true" : "false") << "\n"; //true
    std::cout << (a == c ? "true" : "false") << "\n"; //false

    std::cout << (a < b ? "true" : "false") << "\n"; //false
    std::cout << (a < c ? "true" : "false") << "\n"; //true

}
Run Code Online (Sandbox Code Playgroud)

C++20 应该给我们带来默认比较(https://en.cppreference.com/w/cpp/language/default_comparisons)。所以如果类定义operator<=>为违约,编译器会自动生成==!=<<=>>=运营商以及代码为他们:

struct Point {
    int x;
    int y;
    int z;    

    auto operator<=>(const Point&) const = default;
};
Run Code Online (Sandbox Code Playgroud)