正如大多数程序员所钦佩并尝试遵循Literate编程的原则,但在C ++中,我经常发现自己使用std::pair
来完成大量的常见任务。但std::pair
是,恕我直言,文学节目的邪恶敌人......
我的观点是,当我回到我一两天前编写的代码时,我看到对std::pair
的操纵(通常作为迭代器)我不知道自己“是什么让它自己做了什么 - > first和iter-> second意味着??? “。
我猜其他人在查看他们的std::pair
代码时也有同样的疑问,所以我想知道,有没有人在使用std::pair
时想出一些很好的解决方案来恢复识字?
答案 0 :(得分:17)
std::pair
是使用基本上匿名列创建“本地”和基本上匿名类型的好方法;如果你在一个如此大的词汇空间上使用某个对,你需要命名类型和列,我会改为使用普通的struct
。
答案 1 :(得分:6)
这个怎么样:
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" );
除此之外,我看不到任何可以使事情变得更加清晰的银弹。
答案 2 :(得分:4)
typedef std::pair<bool, int> IsPresent_Value;
typedef std::pair<double, int> Price_Quantity;
...你明白了。
答案 3 :(得分:2)
你可以创建两对getter(const和non),它们只返回对第一个和第二个的引用,但是更具可读性。例如:
string& GetField(pair& p) { return p.first; }
int& GetValue(pair& p) { return p.second; }
可以让你从给定的对中获得字段和值,而不必记住哪个成员拥有什么。
如果您希望大量使用它,您还可以创建一个宏,根据名称和类型为您生成这些getter:MAKE_PAIR_GETTERS(Field,string,Value,int)等等。让getter直截了当可能会让编译器对它们进行优化,因此它们在运行时不会增加任何开销;并且使用宏可以快速创建那些用于对的任何用途的getter。
答案 4 :(得分:2)
最近,我发现自己使用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
确实将身份和价值联系在一起。
答案 5 :(得分:2)
你可以使用boost元组,但它们并没有真正改变底层问题:你的真的想要用一个小整数类型访问对/元组的每个部分,或者你想要吗?更“识字”的代码。见this question我发布了一段时间。
然而,boost::optional是一个有用的工具,我发现它取代了很多对/元组被吹捧作为答案的情况。
答案 6 :(得分:1)
正如Alex所说,std::pair
非常方便,但当它变得混乱时创建一个结构并以相同的方式使用它,看看std::pair
代码,它并不复杂。
答案 7 :(得分:1)
我不喜欢std :: map中使用的std :: pair,映射条目应该有成员键和值。
我甚至使用boost :: MIC来避免这种情况。但是,boost :: MIC也需要付出代价。
此外,返回std ::对会产生不太可读的代码:
if (cntnr.insert(newEntry).second) { ... }
???
我还发现std :: pair常用于懒惰的程序员,他们需要2个值,但没想到为什么这些值需要在一起。