2016-03-02 2 views
3

У меня есть этот случай:станд :: кортеж против станд :: массив в качестве предметов в станд :: вектор

std::vector<4_integers> v; 

Что будет соответствовать лучше здесь?

std::tuple решение:

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

std::array решение:

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

и почему?

EDIT (Прецедент):

Извините за не отметить, что и раньше. Я собираюсь использовать его следующим образом:

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

Конечно, я должен держать их сохранить, так как вычисления 4 целых числа не то, что я хочу, чтобы снова и снова повторить.

+3

И может быть решение * некоторые * проблема ... и теперь все зависит от того, что * * конкретная проблема вы сталкиваетесь. Обратите внимание, что все проблемы не равны, так же как все решения не равны. – Nawaz

+0

Зависит от того, как вы будете их использовать. – marom

+0

В чем проблема? –

ответ

2

Для этого конкретного случая мне придется не согласиться с комментариями. Для контейнеров однородного типа - как в данном случае (все int s) - array превосходит.

При взгляде на интерфейс std::tuple против std::array, очень ясно, что последний является контейнером (с итераторами, например), а первый - нет. Это означает, что остальная часть стандартной библиотеки будет гораздо более естественно применима к последней.

Если типы не были однородными, не было бы вопроса - это должно было быть std::tuple.

+0

Вы делаете много предположений о случае использования OP, когда он еще не сказал нам, какую проблему он пытается решить. Насколько нам известно, у него могут быть тысячи строк кода, основанных на std :: tuple. Или 'int' в кортеже может фактически исходить из индивидуальных аргументов шаблона, которые просто оказываются равными в одном конкретном случае. –

+0

Типы могут быть однородными случайно (что вдохновило меня ответить) –

+0

Да, вы оба правы - ответ предполагает, что типы однородны с некоторым значением. Хорошая точка зрения. –

2

Это зависит от варианта использования, но если элементы как-то связаны, я бы выбрал array. Вы можете перебирать массив и использовать с ними алгоритмы std.

Я обычно думаю tuple в качестве замены на что-то вы могли бы заменить с struct как:

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

tuple Иногда это просто более компактным/ясно, чем новый struct.

4

На мой взгляд, это зависит от того, является ли факт, что это 4 int s является случайным или если он исходит из того, что это тот же тип данных.

Предпочитаете array, если это связанные номера, которые должны иметь одинаковый тип (например, оценки, которые студент имеет на 4 экзаменах). Вы можете перебирать на них, их типы связаны между собой ...

tuple Предпочитают или struct/class если эти 4 int s, которые не связаны, как правило, не имеют одинаковый размер (например, сопротивление, максимальное напряжение, длина ... резистора).

Еще один способ решить, можете ли вы в какой-то момент в будущем изменить тип одного из значений, а не других?

Теперь, конечно, есть случаи на краю. Например, как насчет длины, ширины и высоты коробки? Все они имеют одинаковый размер (например, метры), но они имеют различный смысл. Итерация на них на самом деле не имеет большого смысла. Это зависит от того, как вы используете его в своем коде и как вы видите данные, с которыми работаете.

Лично в большинстве случаев, где может использоваться tuple, я бы предпочел использовать class, поскольку он обеспечивает гораздо более читаемый код и гораздо большую гибкость для эволюции: вы предоставляете значимые имена, вы выбираете видимость атрибутов, вы можете инкапсулировать информацию, вы можете хелперы поставщик методы ...

Такой код:

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

Или даже, если вы хотите, чтобы предотвратить смешивание ширину, длину и высоту (см пункт 18 Скотта Майерса 'Effective C++):

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

является более удобным для чтения, проверяемым и maintanable (на мой взгляд), чем:

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

Хорошие очки.

Смежные вопросы