如何不迷失在执行'<'对于多变量结构

How not to get lost in implementation of '<' for multi-variable structures

本文关键字:于多 变量 结构 何不 执行 迷失      更新时间:2023-10-16

类似于'<&#39;对于多变量结构,我正在为具有多个值的结构实现小于运算符。我不担心使用相等或小于操作符,让我们假设所有成员都正确地实现了这两个操作符。我的结构有四个字段,操作符已经变得相当混乱了:

struct Key {
    std::string s_name;
    bool b_mipmaps;
    bool b_clamp_to_edge;
    GLenum n_intformat;
    // [constructors here]
    bool operator <(const Key &other) const
    {
        return s_name < other.s_name || (s_name == other.s_name && (
            b_mipmaps < other.b_mipmaps || (b_mipmaps == other.b_mipmaps && (
            b_clamp_to_edge < other.b_clamp_to_edge || (b_clamp_to_edge == other.b_clamp_to_edge && (
            n_intformat < other.n_intformat))))));
        // compare two keys
    }
}

我想知道是否有一种常用的缩进风格或一些东西可以帮助你不要迷失在括号中,因为坦率地说,它是地狱,我想这样一个操作符中的错误将是相当微妙的,很难追踪/调试。有没有办法把它分解成一些基本的函数?或者有一个STL函数可以做到这一点?

我目前使用的是c++ 03,但我对新标准持开放态度。

您可以使用std::tie:

bool operator <(const Key &other) const
{
    return std::tie(s_name, b_mipmaps, b_clamp_to_edge, n_intformat) <
        std::tie(other.s_name, other.b_mipmaps, other.b_clamp_to_edge, other.n_intformat);
}

不要忘记#include <tuple>

您可以使用几个if

bool operator <(const Key &other) const
{
    if (s_name != other.s_name) return s_name < other.s_name;
    if (!b_mipmaps && other.b_mipmaps) return true;
    if (b_mipmaps && !other.b_mipmaps) return false;
    if (!b_clamp_to_edge && other.b_clamp_to_edge) return true;
    if (b_clamp_to_edge && !other.b_clamp_to_edge) return false;
    return n_intformat < other.n_intformat;
    // compare two keys
}

不知道代码中变量的类型,我发现很难使用变量名来建议一些事情。

从您的代码中,不清楚操作符的语义应该是什么,如果

(this->b_mipmaps && other.b_mipmaps)true

我使用以下模式:

bool operator <(const Key &other) const
{
   if ( this->member1 != other.member1 )
   {
      return (this->member1 < other.member1);
   }
   if ( this->member2 != other.member2 )
   {
      return (this->member2 < other.member2);
   }
   //
   // ...
   //
   return (this->memberN < other.memberN);
}

编辑

现在我知道b_mipmaps的类型是bool,你可以使用:

   if ( this->b_mipmaps != other.b_mipmaps )
   {
      return (this->b_mipmaps < other.b_mipmaps);
   }

   if ( this->b_mipmaps != other.b_mipmaps )
   {
      return (!(this->b_mipmaps) && other.b_mipmaps);
   }

选择你觉得更容易读懂的样式。

关于@lisyarus的回答很好,但避免了重复字段名:

bool operator <(const Key &other) const
{
    auto fields = [](decltype(*this) v) {
        return std::tie(v.s_name, v.b_mipmaps, v.b_clamp_to_edge, v.n_intformat);
    };
    return (fields(*this) < fields(rhs));
}