文字编码与文字编码 std::pair,解决方案?

发布于 2024-07-25 08:33:43 字数 319 浏览 10 评论 0原文

与大多数程序员一样,我钦佩并尝试遵循文学编程的原则,但在 C++ 中,我经常发现自己使用 std::pair 来完成无数的常见任务。 但是,恕我直言,std::pair 是文学编程的邪恶敌人……

我的观点是,当我回到一两天前编写的代码时,我看到了对std::pair (通常作为迭代器)我想知道“iter->first 和 iter->second 是什么意思???”。

我猜其他人在查看他们的 std::pair 代码时也有同样的疑问,所以我想知道是否有人想出一些好的解决方案来在使用 std:: 时恢复读写能力配对?

As most programmers I admire and try to follow the principles of Literate programming, but in C++ I routinely find myself using std::pair, for a gazillion common tasks. But std::pair is, IMHO, a vile enemy of literate programming...

My point is when I come back to code I've written a day or two ago, and I see manipulations of a std::pair (typically as an iterator) I wonder to myself "what did iter->first and iter->second mean???".

I'm guessing others have the same doubts when looking at their std::pair code, so I was wondering, has anyone come up with some good solutions to recover literacy when using std::pair?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

╰沐子 2024-08-01 08:33:43

std::pair 是使用本质上匿名列创建“本地”且本质上匿名类型的好方法; 如果您在如此大的词汇空间中使用某个对,以至于需要命名类型和列,那么我会使用普通的 struct 来代替。

std::pair is a good way to make a "local" and essentially anonymous type with essentially anonymous columns; if you're using a certain pair over so large a lexical space that you need to name the type and columns, I'd use a plain struct instead.

烟花肆意 2024-08-01 08:33:43

怎么样:

struct MyPair : public std::pair < int, std::string >
{
    const int& keyInt() { return first; }
    void keyInt( const int& keyInt ) { first = keyInt; }
    const std::string& valueString() { return second; }
    void valueString( const std::string& valueString ) { second = valueString; }
};

这有点冗长,但是在代码中使用它可能会使事情更容易阅读,例如:

std::vector < MyPair > listPairs;

std::vector < MyPair >::iterator iterPair( listPairs.begin() );
if ( iterPair->keyInt() == 123 )
    iterPair->valueString( "hello" );

除此之外,我看不到任何能让事情变得更清晰的灵丹妙药。

How about this:

struct MyPair : public std::pair < int, std::string >
{
    const int& keyInt() { return first; }
    void keyInt( const int& keyInt ) { first = keyInt; }
    const std::string& valueString() { return second; }
    void valueString( const std::string& valueString ) { second = valueString; }
};

It's a bit verbose, however using this in your code might make things a little easier to read, eg:

std::vector < MyPair > listPairs;

std::vector < MyPair >::iterator iterPair( listPairs.begin() );
if ( iterPair->keyInt() == 123 )
    iterPair->valueString( "hello" );

Other than this, I can't see any silver bullet that's going to make things much clearer.

往日情怀 2024-08-01 08:33:43
typedef std::pair<bool, int> IsPresent_Value;
typedef std::pair<double, int> Price_Quantity;

...你明白了。

typedef std::pair<bool, int> IsPresent_Value;
typedef std::pair<double, int> Price_Quantity;

...you get the point.

青衫负雪 2024-08-01 08:33:43

您可以创建两对 getter(常量和非),它们仅返回对第一个和第二个的引用,但更具可读性。 例如:

string& GetField(pair& p) { return p.first; }
int& GetValue(pair& p) { return p.second; }

将让您从给定对中获取字段和值成员,而不必记住哪个成员包含什么。

如果您希望经常使用它,您还可以创建一个宏,根据名称和类型为您生成这些 getter:MAKE_PAIR_GETTERS(Field, string, Value, int) 等。 让 getter 变得简单可能会允许编译器优化它们,因此它们不会在运行时增加任何开销; 使用宏可以轻松地为您对成对的任何用途创建这些吸气剂。

You can create two pairs of getters (const and non) that will merely return a reference to first and second, but will be much more readable. For instance:

string& GetField(pair& p) { return p.first; }
int& GetValue(pair& p) { return p.second; }

Will let you get the field and value members from a given pair without having to remember which member holds what.

If you expect to use this a lot, you could also create a macro that will generate those getters for you, given the names and types: MAKE_PAIR_GETTERS(Field, string, Value, int) or so. Making the getters straightforward will probably allow the compiler to optimize them away, so they'll add no overhead at runtime; and using the macro will make it a snap to create those getters for whatever use you make of pairs.

浅浅淡淡 2024-08-01 08:33:43

您可以使用 boost 元组,但它们并不能真正改变根本问题:您是否真的想要使用小型整数类型访问对/元组的每个部分,或者您想要更多的“文化” ' 代码。 请参阅我不久前发布的这个问题

但是,boost::可选是一个有用的工具,我发现它取代了很多将成对/元组吹捧为答案的情况。

You could use boost tuples, but they don't really alter the underlying issue: Do your really want to access each part of the pair/tuple with a small integral type, or do you want more 'literate' code. See this question I posted a while back.

However, boost::optional is a useful tool which I've found replaces quite a few of the cases where pairs/tuples are touted as ther answer.

风追烟花雨 2024-08-01 08:33:43

最近我发现自己使用 boost::tuple 作为 std::pair 的替代品。 您可以为每个成员定义枚举器,因此每个成员的含义很明显:

typedef boost::tuple<int, int> KeyValueTuple;
enum {
  KEY
  , VALUE
};

void foo (KeyValueTuple & p) {
    p.get<KEY> () = 0;
    p.get<VALUE> () = 0;
}

void bar (int key, int value)
{
  foo (boost:tie (key, value));
}

顺便说一句,如果使用此方法存在隐藏成本,欢迎发表评论。

编辑:从全局范围中删除名称。

只是关于全局命名空间的快速评论。 一般来说,我会使用:

struct KeyValueTraits
{
  typedef boost::tuple<int, int> Type;
  enum {
    KEY
    , VALUE
  };
};

void foo (KeyValueTuple::Type & p) {
    p.get<KeyValueTuple::KEY> () = 0;
    p.get<KeyValueTuple::VALUE> () = 0;
}

看起来确实是这样, boost::fusion 确实将身份和价值更紧密地联系在一起。

Recently I've found myself using boost::tuple as a replacement for std::pair. You can define enumerators for each member and so it's obvious what each member is:

typedef boost::tuple<int, int> KeyValueTuple;
enum {
  KEY
  , VALUE
};

void foo (KeyValueTuple & p) {
    p.get<KEY> () = 0;
    p.get<VALUE> () = 0;
}

void bar (int key, int value)
{
  foo (boost:tie (key, value));
}

BTW, comments welcome on if there is a hidden cost to using this approach.

EDIT: Remove names from global scope.

Just a quick comment regarding global namespace. In general I would use:

struct KeyValueTraits
{
  typedef boost::tuple<int, int> Type;
  enum {
    KEY
    , VALUE
  };
};

void foo (KeyValueTuple::Type & p) {
    p.get<KeyValueTuple::KEY> () = 0;
    p.get<KeyValueTuple::VALUE> () = 0;
}

It does look to be the case that boost::fusion does tie the identity and value closer together.

心房的律动 2024-08-01 08:33:43

正如 Alex 提到的,std::pair 非常方便,但是当创建一个结构并以相同的方式使用它变得令人困惑时,请查看 std::pair 代码,没那么复杂。

As Alex mentioned, std::pair is very convenient but when it gets confusing create a structure and use it in the same way, have a look at std::pair code, it's not that complex.

永不分离 2024-08-01 08:33:43

我也不喜欢 std::map 中使用的 std::pair,映射条目应该有成员键和值。
我什至使用 boost::MIC 来避免这种情况。 然而,boost::MIC 也是有代价的。

另外,返回 std::pair 会导致代码可读性较差:

if (cntnr.insert(newEntry).second) { ... }

???

我还发现 std::pair 常被懒惰的程序员使用,他们需要 2 个值,但没有想到为什么需要一起使用这些值。

I don't like std::pair as used in std::map either, map entries should have had members key and value.
I even used boost::MIC to avoid this. However, boost::MIC also comes with a cost.

Also, returning a std::pair results in less than readable code:

if (cntnr.insert(newEntry).second) { ... }

???

I also found that std::pair is commonly used by the lazy programmers who needed 2 values but didn't think why these values where needed together.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文