简体   繁体   中英

std::tuple vs std::array as items of a std::vector

I have this case:

std::vector<4_integers> v;

What would fit best here?

std::tuple solution:

std::vector<std::tuple<int,int,int,int>> v;

std::array solution:

std::vector<std::array<int,4>> v;

and why?

EDIT (The use case):

Sorry for not mentioning that before. I am going to use it as follow:

for(const auto& item:v){
   some_function(item[0],item[1],item[2],item[3]); // or tuple equivalent 
}

Of course I need to keep them stored because computing the 4 integers is not a thing that I want to repeat again and again.

In my opinion, it depends if the fact that these are 4 int s is accidental or if it comes from the fact that it's the same type of data.

Prefer array if these are related numbers that should all have the same type (for example grades that a student has on 4 exams). You may want to iterate on these, their types are linked ...

Prefer tuple or a struct / class if these are 4 int s that are not related, typically that do not have the same dimension (for example resistance, max voltage, length ... of a resistor).

Another way to decide is, could you, at some point in the future, want to change the type of one of the values and not the others ?

Now there are cases on the edge of course. For example, what about length, width and height of a box ? They all have the same dimension (meters for example) but they have different meaning. Iterating on them doesn't really make much sense. It really depends on how you use it in your code and the way you see the data you're working with.

Personally, in most cases where tuple can be used, I'd prefer using a class as it provides much more readable code and much more flexibility for evolution: you provide meaningful names, you decide of the visibility of the attributes, you can encapsulate information, you can provide helper methods ...

This kind of code:

BoxSize clothesBoxSize(5, 4, 10); 
double volume = clothesBoxSize.Volume();

Or even, if you want to prevent mixing width, length and height (see item 18 of Scott Meyers' Effective C++ ):

BoxSize clothesBoxSize(Length(5), Width(4), Height(10));
double volume = clothesBoxSize.Volume();

is more readable, testable and maintanable (in my opinion) than:

std::tuple<int, int, int> clothesBoxSize{5, 4, 10};
double volume = clothesBoxSize[0] * clothesBoxSize[1] * clothesBoxSize[2];

For this specific case, I'd have to disagree with the comments. For homogeneous type containers - as is the case here (all int s) - array is superior.

When looking at the interface of std::tuple vs. std::array , it is very clear that the latter is a container (with iterators, eg), while the former is not. This means that the rest of the standard library will be much more naturally applicable to the latter.

If the types weren't homogeneous, there wouldn't be a question - it would have to be std::tuple .

This depends a lot on the use case, but if the elements are somehow related, I would choose array . You can iterate over array and use std algorithms with them.

I usually think tuple as a substitute to something you could replace with a struct like:

struct fourIntegers{
  int int1;
  int int2;
  int int3;
  int int4;
};

Sometimes the tuple is just more compact/clear than a new struct .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM