В этом смысле это никак не отличается от структур: в структуре добавляется тип и имя в списке полей, в кортеже — тип в списке типов элементов.
Если нам внезапно нужны осмысленные имена полей, кортеж не виноват, что мы выбрали его вместо структуры.
Ну и дальше что? :) Вы спросили как сделать без вложенности пар, я показал. Про понятность такого кода в комментарии, на который я отвечал, речи не было.
По поводу использования pair/tuple в неподходящих местах могу только процитировать анегдот:
Пациент:
— Доктор, мне больно, когда я делаю так — и изгибается в бараний рог.
Доктор:
— Так не делайте так
Оно без VS пока даже ставиться отказывается (авторы говорят своего препроцессора в PVS ещё нет). Я сам для тех же целей хотел погонять тестовую версию PVS и обломался.
У нас помнится представители заказчика увидели на процессорном модуле светодиод активности доступа к воткнутой CF-ке и попросили подробную инструкцию о том при каких условиях и с какой частотой он моргает.
Если я правильно понял чего хотел добиться автор, то это весьма близко к идее концептов в С++.
Основное отличие в том, что концепты предназначены для проверки параметров шаблонов, а не функций, что требует делать шаблонными все функции, принимающие такие параметры (что в принципе и без концептов можно наблюдать в STL), но избавляет от вызовов виртуальных функций.
Если скоростные вызовы методов классов не нужны, последнее ограничение можно было бы попробовать обойти с помощью type erasure.
В С++, насколько я слышал и наблюдал сам, оптимизируется не случай, когда исключение выбрасывается, а случай, когда оно не выбрасывается (т.н. zero-cost exception handling). Т.е. разработчики компилятора считают, что вы будете кидаться исключениями только в редких нештатных ситуациях.
У себя тоже в «синтетическом» примере я наблюдал разницу где-то в 1-3%, которая в зависимости от поведения оптимизатора в компиляторе (без указания inline отказался автоматически инлайнить функцию с исключением) была в пользу исключений или в пользу возврата кода ошибки.
Если нам внезапно нужны осмысленные имена полей, кортеж не виноват, что мы выбрали его вместо структуры.
По поводу использования pair/tuple в неподходящих местах могу только процитировать анегдот:
&fooи*foo.Основное отличие в том, что концепты предназначены для проверки параметров шаблонов, а не функций, что требует делать шаблонными все функции, принимающие такие параметры (что в принципе и без концептов можно наблюдать в STL), но избавляет от вызовов виртуальных функций.
Если скоростные вызовы методов классов не нужны, последнее ограничение можно было бы попробовать обойти с помощью type erasure.
P.S.
Помимо Boost Concept Check есть ещё другая библиотека (насколько я понял, рассчитанная на C++0x), реализующая идею концептов. Вот слайды её презентации с BoostCon 2011: https://github.com/boostcon/2011_presentations/raw/master/thu/Boost.Generic.pdf
P.P.S.
Раз уж я упомянул STL грех не вспомнить про tag dispatching и другие техники обобщенного программрования в C++ (главное ими чрезмерно не увлекаться).
У меня лично от такого обилия белого на экране глаза напрягаются как от созерцания включенной лампочки.
У себя тоже в «синтетическом» примере я наблюдал разницу где-то в 1-3%, которая в зависимости от поведения оптимизатора в компиляторе (без указания inline отказался автоматически инлайнить функцию с исключением) была в пользу исключений или в пользу возврата кода ошибки.
Т.е. хотя бы так:
constexpr int fact(int n) { return n > 0 ? fact(n - 1) : 1; }