结构有2个单元格vs std :: pair? [重复]

时间:2021-03-19 11:12:25

Possible Duplicate:
What is the difference between using a struct with two fields and a pair?

可能重复:使用带有两个字段和一对的结构有什么区别?

Dear all,

I have a little question about pairs and struct. Is there any advantage to use a std::pair instead of a struct with two cells ? I have used pairs for a while but the main problem is readability : If you want to represent for example a duple (int "label", double "value") you can use either a :

关于对和结构,我有一个小问题。使用std :: pair而不是带有两个单元格的结构有什么好处吗?我已经使用了一段时间,但主要问题是可读性:如果你想表示例如一个双重(int“标签”,双“值”),你可以使用:

typedef std::pair<int,double> myElem;

or a

typedef struct {
    int label;
    double value;
} myElem;

The code becomes more readable if your statements have a "semantic" sense (you will always know what x.label is. that's not the case with x.first).

如果你的语句具有“语义”意义,那么代码就会变得更具可读性(你将永远知道x.label是什么。这与x.first不同)。

However, I guess there is an advantage using pair. Is it more performant or something else?

但是,我猜使用pair有一个优势。它更高效还是其他什么?

5 个解决方案

#1


3  

A pair is implemented as a templated struct. It provides you with a shorthand for creating a (typically heterogenous) pair. Also, there are some constraints on the types that you can use with a pair:

一对被实现为模板化结构。它为您提供了创建(通常是异质的)对的简写。此外,对于可以与一对使用的类型存在一些限制:

Type requirements

T1 and T2 must both be models of Assignable. Additional operations have additional requirements. Pair's default constructor may only be used if both T1 and T2 are DefaultConstructible, operator== may only be used if both T1 and T2 are EqualityComparable, and operator< may only be used if both T1 and T2 are LessThanComparable.

T1和T2必须都是可分配的模型。其他操作有其他要求。如果T1和T2都是DefaultConstructible,则只能使用Pair的默认构造函数,仅当T1和T2都是EqualityComparable时才可以使用operator ==,而只有T1和T2都是LessThanComparable时才可以使用operator <。

(from SGI STL std::pair documentation)

(来自SGI STL std :: pair文档)

Defining your own POD may make sense if the types do not follow any of these constraints or if you do not care about them.

如果类型不遵循任何这些约束或者您不关心它们,那么定义您自己的POD可能是有意义的。

Finally, I guess it is a matter of personal choice/coding style.

最后,我想这是个人选择/编码风格的问题。

#2


12  

In terms of performance: it's unlikely to change anything, you're just sugar coating it.

在性能方面:它不太可能改变任何东西,你只是糖涂层。

In terms of usability, I would rather use a custom struct, which can be declared this way (by the way):

在可用性方面,我宁愿使用自定义结构,可以通过这种方式声明(顺便说一下):

struct MyElement
{
  int label;
  double value;
};

I am a strong proponent of strong typing, and I much prefer a "real" structure (and better yet, class) than an ad-hoc tuple whenever it's more than a fleeting thing.

我是强打字的强烈支持者,而且我更喜欢“真正的”结构(更好的是,类),而不是一个特殊的元组,只要它不仅仅是一个稍纵即逝的东西。

Mainly because:

  • As you noted first and second don't carry much meaning
  • 正如你所指出的那样,第一次和第二次没有多大意义

  • You cannot add methods / other fields to a std::pair
  • 您不能将方法/其他字段添加到std :: pair

  • You cannot add class invariants to a std::pair
  • 您不能将类不变量添加到std :: pair

All in all, I really think that maintenance benefits from using a custom dedicated structure that a one-size-fits-them-all tuple.

总而言之,我真的认为维护可以从使用一个适合所有元组的自定义专用结构中受益。

#3


4  

However, I guess there is an advantage using pair. Is it more performant or something else?

但是,我猜使用pair有一个优势。它更高效还是其他什么?

I doubt it, an instantiated std::pair is just a struct, after all. std::pair comes with operator< defined, though. But that shouldn't be too hard to do yourself for a struct with only two members.

我对此表示怀疑,毕竟实例化的std :: pair只是一个结构体。但是,std :: pair附带了operator 。但对于只有两个成员的结构来说,这不应该太难。

So I usually do as you reasoned: a struct with dedicated member names is easier to read than first and second.

所以我通常按照你的推理做:具有专用成员名称的结构比第一和第二更容易阅读。

#4


4  

Its primary advantage is that it's generic. For example, when you retrieve something from an std::map, you get the key and the associated value as the first and second items in an std::pair.

它的主要优点是它是通用的。例如,当您从std :: map中检索某些内容时,您将获得密钥和关联值作为std :: pair中的第一项和第二项。

Likewise, when you use std::equal_range to find a set of equal values in a collection, you get iterators to the beginning and end of the range as the first and second items in an std::pair.

同样,当您使用std :: equal_range在集合中查找一组相等的值时,您将获得作为std :: pair中第一个和第二个项的范围的开头和结尾的迭代器。

It's hard to imagine meaningful labels that would apply to both of these, so they settled for a couple that don't mean very much, but at least aren't misleading. Using 'key' and 'data' would work for std::map, but be misleading for std::equal_range (and if you switched to something like lower_bound and upper_bound to make them more meaningful for std::equal_range, it'd be equally wrong for items in std::map).

很难想象有意义的标签会适用于这两种标签,所以他们选择了一对并不意味着很多的标签,但至少没有误导。使用'key'和'data'可以用于std :: map,但是对std :: equal_range会产生误导(如果你切换到类似lower_bound和upper_bound的东西,使它们对std :: equal_range更有意义,那就是对于std :: map中的项目同样错误。

#5


2  

With a std::pair, you are free to use functors from the STL such as select1st or select2nd. Likewise it allows you to use other generic functions with your pair, such as operator< and others. Admittedly, with the advent of boost/tr1, you could achieve much the same effect by using bind.

使用std :: pair,您可以*地使用STL中的仿函数,例如select1st或select2nd。同样,它允许您对您的对使用其他通用函数,例如operator <和其他。不可否认,随着boost tr1的出现,使用bind可以达到同样的效果。< p>

Your point about readability is very true though.

关于可读性,你的观点非常正确。

#1


3  

A pair is implemented as a templated struct. It provides you with a shorthand for creating a (typically heterogenous) pair. Also, there are some constraints on the types that you can use with a pair:

一对被实现为模板化结构。它为您提供了创建(通常是异质的)对的简写。此外,对于可以与一对使用的类型存在一些限制:

Type requirements

T1 and T2 must both be models of Assignable. Additional operations have additional requirements. Pair's default constructor may only be used if both T1 and T2 are DefaultConstructible, operator== may only be used if both T1 and T2 are EqualityComparable, and operator< may only be used if both T1 and T2 are LessThanComparable.

T1和T2必须都是可分配的模型。其他操作有其他要求。如果T1和T2都是DefaultConstructible,则只能使用Pair的默认构造函数,仅当T1和T2都是EqualityComparable时才可以使用operator ==,而只有T1和T2都是LessThanComparable时才可以使用operator <。

(from SGI STL std::pair documentation)

(来自SGI STL std :: pair文档)

Defining your own POD may make sense if the types do not follow any of these constraints or if you do not care about them.

如果类型不遵循任何这些约束或者您不关心它们,那么定义您自己的POD可能是有意义的。

Finally, I guess it is a matter of personal choice/coding style.

最后,我想这是个人选择/编码风格的问题。

#2


12  

In terms of performance: it's unlikely to change anything, you're just sugar coating it.

在性能方面:它不太可能改变任何东西,你只是糖涂层。

In terms of usability, I would rather use a custom struct, which can be declared this way (by the way):

在可用性方面,我宁愿使用自定义结构,可以通过这种方式声明(顺便说一下):

struct MyElement
{
  int label;
  double value;
};

I am a strong proponent of strong typing, and I much prefer a "real" structure (and better yet, class) than an ad-hoc tuple whenever it's more than a fleeting thing.

我是强打字的强烈支持者,而且我更喜欢“真正的”结构(更好的是,类),而不是一个特殊的元组,只要它不仅仅是一个稍纵即逝的东西。

Mainly because:

  • As you noted first and second don't carry much meaning
  • 正如你所指出的那样,第一次和第二次没有多大意义

  • You cannot add methods / other fields to a std::pair
  • 您不能将方法/其他字段添加到std :: pair

  • You cannot add class invariants to a std::pair
  • 您不能将类不变量添加到std :: pair

All in all, I really think that maintenance benefits from using a custom dedicated structure that a one-size-fits-them-all tuple.

总而言之,我真的认为维护可以从使用一个适合所有元组的自定义专用结构中受益。

#3


4  

However, I guess there is an advantage using pair. Is it more performant or something else?

但是,我猜使用pair有一个优势。它更高效还是其他什么?

I doubt it, an instantiated std::pair is just a struct, after all. std::pair comes with operator< defined, though. But that shouldn't be too hard to do yourself for a struct with only two members.

我对此表示怀疑,毕竟实例化的std :: pair只是一个结构体。但是,std :: pair附带了operator 。但对于只有两个成员的结构来说,这不应该太难。

So I usually do as you reasoned: a struct with dedicated member names is easier to read than first and second.

所以我通常按照你的推理做:具有专用成员名称的结构比第一和第二更容易阅读。

#4


4  

Its primary advantage is that it's generic. For example, when you retrieve something from an std::map, you get the key and the associated value as the first and second items in an std::pair.

它的主要优点是它是通用的。例如,当您从std :: map中检索某些内容时,您将获得密钥和关联值作为std :: pair中的第一项和第二项。

Likewise, when you use std::equal_range to find a set of equal values in a collection, you get iterators to the beginning and end of the range as the first and second items in an std::pair.

同样,当您使用std :: equal_range在集合中查找一组相等的值时,您将获得作为std :: pair中第一个和第二个项的范围的开头和结尾的迭代器。

It's hard to imagine meaningful labels that would apply to both of these, so they settled for a couple that don't mean very much, but at least aren't misleading. Using 'key' and 'data' would work for std::map, but be misleading for std::equal_range (and if you switched to something like lower_bound and upper_bound to make them more meaningful for std::equal_range, it'd be equally wrong for items in std::map).

很难想象有意义的标签会适用于这两种标签,所以他们选择了一对并不意味着很多的标签,但至少没有误导。使用'key'和'data'可以用于std :: map,但是对std :: equal_range会产生误导(如果你切换到类似lower_bound和upper_bound的东西,使它们对std :: equal_range更有意义,那就是对于std :: map中的项目同样错误。

#5


2  

With a std::pair, you are free to use functors from the STL such as select1st or select2nd. Likewise it allows you to use other generic functions with your pair, such as operator< and others. Admittedly, with the advent of boost/tr1, you could achieve much the same effect by using bind.

使用std :: pair,您可以*地使用STL中的仿函数,例如select1st或select2nd。同样,它允许您对您的对使用其他通用函数,例如operator <和其他。不可否认,随着boost tr1的出现,使用bind可以达到同样的效果。< p>

Your point about readability is very true though.

关于可读性,你的观点非常正确。