【问题标题】:Is there a way to have a compile time check, that all members of a class are compared within operator==有没有办法进行编译时检查,一个类的所有成员都在 operator== 中进行比较
【发布时间】:2021-06-12 14:19:14
【问题描述】:

我想知道 C++ 中是否有一种方法可以进行编译时检查,以验证一个类的所有成员变量是否由operator== 进行比较?如果有的话,有一种方法可以明确地忽略某些成员上的这个约束也是有用的。

这对于我的用例很有用,其中在我们的开发过程中有一个数据结构随着时间的推移而变化,并且已经多次发生过调整现有的 operator== 被遗忘的情况。这是一个静默错误,它会导致我们称之为“误报行为”,这很难找到。

感谢任何信息。可能是解决问题的替代方法,或者解释为什么这个编译时检查可能不可能。

编辑:遗憾的是,我正在使用 C++17,并且在不久的将来无法更新到 C++20。

【问题讨论】:

  • 不,但在 C++20 中,您可以声明一个 defaulted comparison operator,它会自动比较所有基数和成员。
  • 您可以使用/编写外部工具进行该检查。例如,clang 工具可能允许检查。

标签: c++ operator-overloading c++17 comparison-operators


【解决方案1】:

这里的根本问题是你不能迭代类成员。

快速的解决方案是将所有参与operator==的成员打包到std::tuple中。

【讨论】:

    【解决方案2】:

    对于 C++20,假设您的所有类成员本身都具有 == 可比性,您可以简单地提供一个默认定义:

    class C {
        // members
    public:
        bool operator==(C const&) const = default;
    };
    

    当您更新班级时,默认操作员将自动接收新成员。


    至于忽略比较中的成员。这总是有点牵扯,因为有时可能会出现默认操作。一种方法是使用嵌套类

    class C {
        // members
        struct NoEqCompare {
           mutable std::mutex mut; // A member you may want to omit.
           bool operator==(NoEqCompare const&) const { return true; }
        } eqIgnore;
    public:
        bool operator==(C const&) const = default;
    };
    

    std::tie-ing 以每个运算符为基础的您想要的成员的旧技巧不同,如果我们需要将更多运算符添加到组合中,然后混合和匹配,这可能会更加棘手成员。权衡您的选择。

    【讨论】:

    • 比较所有成员。产生异常并非易事(例如,将异常打包到基类中并使其 operator== 无条件返回 true
    • 啊,是的,遗憾的是我们还没有 C++20 支持。我想这是从 C++20 开始在 C++ 中执行此操作的正确方法。
    • @MSalters - 随意投票。
    • @Mario:它被添加到下一个 C++ 标准的事实确实告诉你,很多人都同意你的观察,它是多么方便。
    • @StoryTeller-UnslanderMonica:我已经投票了;该评论是对改进的建议。该问题要求“一种在某些成员上明确忽略此问题的方法”,我的示例显示了一种可以通过您的答案实现的方法
    猜你喜欢
    • 2014-02-08
    • 1970-01-01
    • 2020-03-13
    • 2021-09-26
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    相关资源
    最近更新 更多