有没有一种方便的方法将 std::pair 包装为新类型?

2024-03-27

我经常发现自己使用 std::pair 将两个相关量的逻辑分组定义为函数参数/返回值。一些示例:行/列、标签/值等。

很多时候我真的应该滚动我自己的类,而不是仅仅使用 std::pair。当事情开始崩溃时,很容易看出 - 当代码中充斥着 make_pair、first 和 secondary 时,很难记住什么是什么 -std::pair<int, int>传达的含义少于类型Position.

您发现将 std::pair 的功能包装在传达真正含义的类型中的最佳方法是什么?

以下是我考虑过的一些事情:

typedef std::pair<int, int> Position;

这至少在传递类型时为该类型提供了一个有意义的名称,但该类型并未强制执行,它实际上仍然只是一对,并且大多数相同的问题仍然存在。然而,这写起来非常简单。

struct Position : public std::pair<int, int>
{
    typedef std::pair<int, int> Base;
    Position() : Base() {}
    Position(const Position &x) : Base(x) {}
    Position(int a, int b) : Base(a, b) {}

    int &row() { return first; }
    const int &row() const { return first; }

    int &col() { return second; }
    const int &col() const { return second; }
};

这更好,因为我们可以通过合理的描述性名称访问变量。这里的问题是你仍然可以访问第一个和第二个,因此抽象很容易泄漏。此外,通过函数访问简单变量会使语法变得烦人。

显而易见的下一步是将继承设为私有:

struct Position : private std::pair<int, int>
{
    typedef std::pair<int, int> Base;
    Position() {}
    Position(const Position &x) : Base(x) {}
    Position(int a, int b) : Base(a, b) {}

    int &row() { return first; }
    const int &row() const { return first; }

    int &col() { return second; }
    const int &col() const { return second; }

    bool operator<(const Position &x) const { return Base(*this) < Base(x); }
    // other forwarding operators as needed...
};

所以现在至少我们已经摆脱了对第一和第二的访问,但现在又出现了一个新问题。当我们想要将类型存储在 std::set 中时,我们现在无法访问operator

struct Position
{
    Position() {}
    Position(const Position &x) : row(x.row), col(x.col) {}
    Position(int row, int col) : row(row), col(col) {}

    int row, col;
};
bool operator<(const Position &a, const Position &b)
{
    return a.row < b.row || (!(b.row < a.row) && a.col < b.col);
}
// more overloads as needed

所以现在我们有了简单的变量访问,但现在定义重载运算符更加痛苦,因为我们不仅将它们转发到该对的实现,而且实际上每次都必须重新实现它们......

有没有我忽略的解决方案可以让这件事变得简单而又没有缺点?如果没有,您会更喜欢哪个?


这是什么升压元组 http://www.boost.org/doc/libs/1_36_0/libs/tuple/doc/tuple_users_guide.html是为.

但你可能应该使用std::元组 http://en.cppreference.com/w/cpp/utility/tuple now...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有没有一种方便的方法将 std::pair 包装为新类型? 的相关文章

随机推荐

  • 当 Node.js 内部仍然依赖于线程时,它如何本质上更快?

    我刚刚观看了以下视频 Node js 简介 http www yuiblog com blog 2010 05 20 video dahl 并且仍然不明白如何获得速度优势 主要是 Ryan Dahl Node js 的创建者 曾经说过 No
  • Android Ion 缓存刷新

    我使用特定的网址在线获取图像 但网址本身每隔几分钟就会自动更改 我正在使用 ION 库Here https github com koush ion我遇到的问题是 当我刷新页面时 页面本身看起来正在刷新 但出现了完全相同的图片 我假设它是缓
  • 使用 Silverlight 的本地数据库

    对于 Silverlight 应用程序来说 什么是好的本地数据库 数据库的主要用途是提供本地数据缓存和同步服务 我不相信 SQL Anywhere 或 SQLite 会工作 因为它们使用非托管代码 无法在 silverlight 沙箱下运行
  • 如何对 Android 应用程序进行定时炸弹?

    大家好 有没有人有一个代码示例 说明如何对 Android 应用程序进行定时炸弹 使其在给定日期后无法运行 我想发布一个 测试版 应用程序进行测试 但希望确保它仅在该应用程序正式处于测试版时才能工作 我建议使用 Calendar 类并让您的
  • Android:从软键盘中删除 Enter 键

    在我的登录表单中 当用户单击 EditText 并按 Enter 键时 会插入一个新行 从而增加 EditText 的大小 下一刻 它返回到之前的位置 并在密码字段 这是下一个字段 中打印一个点 我想从软键盘上删除这个回车键 是否可以 Us
  • Android java.lang.ClassCastException:android.widget.LinearLayout 无法转换为 android.widget.TextView

    我试图打印在 listView 中单击的值 但随后出现以下异常 07 04 10 40 56 482 E AndroidRuntime 1356 FATAL EXCEPTION main 07 04 10 40 56 482 E Andro
  • Reactjs 状态未更新

    constructor props super props this state active false showSideBar false className componentDidMount if this props overla
  • 创建包含所有可能变体的产品数组

    我正在尝试生成一个包含产品所有变体的数组 可以有无限数量的属性和变化 提供的数组 Shirt Product Color Attribute Green Variation Red Blue Size Small Medium Large
  • 什么时候返回右值引用会导致未定义的行为?

    在 Stack Overflow 的回答中here https stackoverflow com a 9964002 1128289 Kerrek 发布了以下代码 Foo g Foo y return y error cannot bin
  • 如何从 JRuby 获取 Java 接口的类型正确的 ruby​​ 实现?

    我正在尝试从 Java 应用程序使用 JRuby 通过 JRuby 1 5 中包含的 JSR233 接口 来加载 Java 接口的 ruby 实现 我的示例实现如下所示 界面 package some package import java
  • SQL 中的连接顺序重要吗?

    不考虑性能 下面的查询 A 和 B 会得到相同的结果吗 C和D怎么样 Scenario 1 A left join select from a left join b on
  • 在skiasharp中加载字体

    如何在 Xamarin 表单的 skiasharp 中使用自定义字体 I tried paint Typeface SKTypeface FromFamilyName CoText Bd and paint Typeface SKTypef
  • 将嵌套列表转换为嵌套字典

    我有这个清单 list1 X1 2 X2 4 Y1 2 Y2 4 我想创建这个字典 dict1 X 1 2 2 4 Y 1 2 2 4 这样我就可以使用dict1 X 1 这输出 2 有人可以帮我吗 我尝试了多种方法但没有成功 您可以使用c
  • C#读取Arduino

    我正在尝试制作一个从 Arduino 读取传出信号的应用程序 但我无法使其在 C 中工作Windows 窗体 http en wikipedia org wiki Windows Forms 仅在控制台中 我的 C Windows 窗体代码
  • 将 url 重写为 url:端口号

    如何重写下一个 url 请求 http mydomain com virtualDirectory default aspx param1 2 param2 car to http mydomain com 8888 virtualDire
  • GraphQL 缺少名称

    刚刚使用 Node 和 C 学习 GraphQL 我正在尝试将 C 示例移植到 Node 因为这将是一个很好的学习练习 因为我不太了解 Node 或 graphql 我有两种类型 帐户和所有者 即帐户所有者 以下内容一切正常 即拥有帐户的字
  • 深层链接导致应用程序的多个实例打开

    这个问题已经在类似的帖子中解决过 但是 我的情况有点不同 我只有一项活动和多个片段 我没有深入链接到特定的片段 我正在启动我的一项活动 然后重定向到不同的片段 我遇到的问题是 当单击深层链接时 应用程序的多个实例正在打开 并且当阻止应用程序
  • 相交矩形的总面积

    用于确定两个相交且可以旋转离开坐标轴的矩形的总面积的算法是什么 以下是您需要做的大致内容 尽可能笼统地表达 但涵盖了所有可能性 计算出交集的类别 IE 相交区域有多少条边 它可以是 0 到 8 之间的任何值 找到交点的所有顶点 这将是矩形边
  • 在播放来自 UIImagePickerController 的视频之前,AVPlayer 不会播放视频

    我遇到了一个问题 我在这里没有看到类似的帖子 我有一个AVPlayerViewController它播放基于我的路径的视频Firebase 数据库 不是存储 该视频按照我想要的方式完美播放 但只有当我观看了在UIImagePickerCon
  • 有没有一种方便的方法将 std::pair 包装为新类型?

    我经常发现自己使用 std pair 将两个相关量的逻辑分组定义为函数参数 返回值 一些示例 行 列 标签 值等 很多时候我真的应该滚动我自己的类 而不是仅仅使用 std pair 当事情开始崩溃时 很容易看出 当代码中充斥着 make p