定义通用比较运算符

Max*_*V37 23 c++ generics

我想出了一个定义一个通用比较运算符的想法,它可以用于任何类型,以获得它的乐趣.

#include <cstring>
#include <iostream>

class A
{
    public:
        A(int id) : id(id) {}

    private:
        int id;
};

template <class T>
inline bool operator==(const T& a, const T& b)
{
    return memcmp(&a, &b, sizeof(a)) == 0; // implementation is unimportant (can fail because of padding)
}

int main()
{
    std::cout << (A(10) == A(10)) << std::endl; // 1
    std::cout << (A(10) == A(15)) << std::endl; // 0
}
Run Code Online (Sandbox Code Playgroud)

我认为这可以用来解决c ++中缺少默认比较运算符的问题.

这是一个糟糕的主意吗?我想知道在某些情况下这样做是否会破坏任何东西?

Bau*_*gen 52

这样做确实是一个糟糕的主意.

如果某些类型没有定义相等运算符,则很可能是因为您无法合理地比较该类型的两个对象是否相等.

即使在缺少平等的经营者由实施者疏忽,在任何情况下,"全面"实现你会想出是高度不可能理智做事.

总结一下:不要这样做!编译时错误优于运行时错误; 而不是过早地添加一个隐藏实际问题的最肯定的"解决方案",在编译时错误发生时添加实际的解决方案.


对于初学者来说,你提出的解决方案对于带填充的类型,带有重载的一元的类型operator&以及任何具有某些指针或引用的类型的成员都是失败的; 甚至是具有任何上述类别的任何成员或基础的类型.因此,对于一的东西.

  • @BЈовић实际上,没有.标准布局类型仍然可能有填充,这往往打破了'memcmp`业务. (4认同)

MSa*_*ers 25

比方说,让我们选一个完全正常的课程String.它是按照您的想法实现的,其中char*指向new[]'ed缓冲区.

现在比较其中两个.显然,String("abc")==String("abc").然而你的实现未通过此测试,因为两个指针不同.

等式由类语义定义,而不是由对象内部的位定义.


was*_*mup 5

是的,这是一个可怕的想法:
如果是未初始化的指针:
这是一个失败的样本(所以这段代码有两个不同的输出):

#include <cstring>
#include <iostream>

class A {
public:
  A(int id) : id(id) {}

private:
  int id;
  A* a;
};

template <class T> inline bool operator==(const T &a, const T &b) {
  return memcmp(&a, &b, sizeof(a)) == 0;
}

int main() {
  std::cout << (A(10) == A(10)) << std::endl; // 1
  std::cout << (A(10) == A(15)) << std::endl; // 0
}
Run Code Online (Sandbox Code Playgroud)

输出:

0
0
Run Code Online (Sandbox Code Playgroud)

并且两个指针的两个相同RAM初始内容值的可能性极小,然后另一个输出是:

1
0
Run Code Online (Sandbox Code Playgroud)

  • 实际上,你的例子有未定义的行为,因为`A`的成员`a`是未初始化的.不保证输出两个零值. (4认同)