Идеальная пара

Вдохновленный этим вопросом, я задумался о том, что является идеальным std::pair должно выглядеть. Класс сжатой пары (например, boost) предоставляет пару, размер которой уменьшается, когда один из ее типов является пустым классом. Для сжатой пары требуются геттеры (first(), second()), чтобы скрыть тот факт, что элемент с пустым типом не существует.

Во-вторых, согласно документам C++: "Пары - это частный случай кортежа" , но они реализованы как отдельный класс. Почему бы не использовать частичные специализации шаблонов, такие как

template <typename ...Args> class tuple {};
template <typename T1, typename T2> class tuple<T1, T2> {}; // Implements a compressed pair
template <typename T1, typename T2> using pair = tuple<T1, T2>;

Кроме того, чтобы обеспечить более унифицированный API, можно было бы перегрузить std::get и std::set для pair и отказаться от методов доступа first() и second(). А можно и то, и другое :)

Вопросы

  1. Почему std::pair не является специализацией std::tuple?

  2. Когда можно использовать std::pair вместо сжатой пары? И даже если есть случаи, должна ли по умолчанию быть сжатая пара?

  3. Почему нет класса сжатого кортежа?


person Judge    schedule 16.06.2016    source источник
comment
Ответ на 1, вероятно, потому, что std::pair был в стандарте задолго до std::tuple появился в C++11.   -  person Some programmer dude    schedule 16.06.2016
comment
@JoachimPileborg Хорошая мысль, однако я не думаю, что обратная совместимость будет нарушена, если переписать std::pair как специализацию std::tuple, оставив открытыми first и second. Хотя, возможно, это вызовет больше путаницы, чем того стоит.   -  person Judge    schedule 16.06.2016


Ответы (1)


  1. pair предшествует tuple на целых 10 лет. Он существует как отдельный класс в основном по историческим причинам и для обратной совместимости. Внесение критических изменений в него доставляет больше хлопот, чем оно того стоит. Если кому-то нужен кортеж из двух элементов, он может просто использовать кортеж из двух элементов.

  2. У меня проблемы с неискусственными примерами, единственной реальной причиной, по моему мнению, является использование стандартных библиотечных классов и обратная совместимость с кодом, предполагающим sizeof(pair<A,B>) >= sizeof(A) + sizeof(B) и тому подобное.

  3. Нет compressed_tuple, так как std::tuple уже выполняет EBO в каждой реализации стандартной библиотеки, достойной их соли.

person Revolver_Ocelot    schedule 16.06.2016
comment
Спасибо за ответ. Я быстро поиграл с tuple и pair, и вот мои результаты. Интересно, что pair никогда не сжимается, а tuple сжимается на g++ и clang++. Итак, я прав в заключении: всегда используйте tuple вместо pair, если только вам не нужно сжатие? И msvc не стоит своих денег? :) - person Judge; 16.06.2016
comment
@ Судите, какую версию msvc вы используете? Я полагаю, что у последнего есть EBO для кортежа. У меня редко возникает потребность в таком сильном сжатии, и большую часть времени я взаимодействую с STL, поэтому обычно я использую пару, если только у меня нет пустого класса и тысячи экземпляров, или общий размер пары превысит размер регистра/имеет более 50% накладных расходов из-за к вопросам согласования. - person Revolver_Ocelot; 16.06.2016
comment
Я использую msvs 2015 Community edition (14.0.25123.00, обновление 2). Справедливо, но сжатие по умолчанию, конечно, не повредит? Если, как вы говорите, вы полагаетесь на его размер. - person Judge; 16.06.2016
comment
@ Судья Конечно, нельзя. Я просто использую стандартную библиотеку + auto, поэтому у меня много пар и не хватает двухэлементных кортежей. Меня не волнует, если это не узкое место: в противном случае я вряд ли заметно уменьшу объем памяти или время выполнения. Что касается компилятора: я не могу помочь с этим. Я не пользуюсь msvs, поэтому не слежу за новостями об этом. Возможно, мне не хватает функции в компиляторе, или мне нужны определенные флаги, или что-то в этом роде. Я полагаю, что стандартный библиотечный кортеж поддерживает EBO. - person Revolver_Ocelot; 16.06.2016
comment
Ах, как плохо, я не знал, что tuple не было в STL. Хорошо, спасибо - я немного покопаюсь в функциях компилятора msvc. - person Judge; 16.06.2016
comment
@Judge Нет, это там, STL в настоящее время относится ко всему, что создано по шаблону из стандартной библиотеки C++ из-за Metonymy - person Revolver_Ocelot; 16.06.2016
comment
Извините, кажется, я неправильно понял... и отсутствие двухэлементных кортежей. это означает, что у вас нет доступа к std::tuple, что, как я предположил, было связано с тем, что вы использовали исходную STL вместо стандартной библиотеки, мой плохой. Правильно ли я понимаю, что у вас много std::pairs в вашем коде, но мало std::tuples, и вы в порядке без сжатия, и поэтому довольны std::pair? - person Judge; 16.06.2016
comment
@Оцените отсутствие двухэлементных кортежей в моем коде. Стандартная библиотека обычно принимает и возвращает пары, поэтому я просто использую нативные типы. - person Revolver_Ocelot; 16.06.2016
comment
Кто-нибудь знает, есть ли сжатие кортежей в gcc 6.2? - person Anoroah; 02.06.2017