эволюция std::make_pair
От: uncommon Ниоткуда  
Дата: 10.09.14 04:11
Оценка: 5 (2) :)))
Такая маленькая функция. Что может быть проще? (по мотивам vimeo.com/97337253)

C++98:
template <typename T1, typename T2>
std::pair<T1, T2> make_pair(T1 const & t1, T2 const & t2) {
    return std::pair<T1, T2>(t1, t2);
}


C++03:
template <typename T1, typename T2>
std::pair<T1, T2> make_pair(T1 t1, T2 t2) {
    return std::pair<T1, T2>(t1, t2);
}


C++11:
template <typename T1, typename T2>
constexpr
std::pair<typename std::decay<T1>::type, typename std::decay<T2>::type>
make_pair(T1 && t1, T2 && t2) {
    return std::pair<typename std::decay<T1>::type, typename std::decay<T2>::type>(std::forward<T1>(t1), std::forward<T2>(t2));
}


C++14:
template <typename T1, typename T2>
constexpr
std::pair<std::decay_t<T1>, std::decay_t<T2>>
make_pair(T1 && t1, T2 && t2) {
    return std::pair<std::decay_t<T1>, std::decay_t<T2>>(std::forward<T1>(t1), std::forward<T2>(t2));
}


C++17?
template <typename T1, typename T2>
constexpr
std::pair<T1, T2> make_pair(T1 t1, T2 t2) {
    return std::pair<T1, T2>(t1, t2);
}
Re: эволюция std::make_pair
От: BulatZiganshin  
Дата: 10.09.14 04:52
Оценка:
Здравствуйте, uncommon, Вы писали:

U>C++17?


а потом снова по циклу! для сравнения в хаскеле:

data (a,b) = (a,b) deriving (Eq,Show...)

сразу описание типа, конструктора, паттерн-матчинга и кучи стандартных операций
Люди, я люблю вас! Будьте бдительны!!!
Re: эволюция std::make_pair
От: Jack128  
Дата: 10.09.14 06:49
Оценка:
Здравствуйте, uncommon, Вы писали:

U>Такая маленькая функция. Что может быть проще? (по мотивам vimeo.com/97337253)


U>C++98:

U>
U>template <typename T1, typename T2>
U>std::pair<T1, T2> make_pair(T1 const & t1, T2 const & t2) {
U>    return std::pair<T1, T2>(t1, t2);
U>}
U>


U>C++03:

U>
U>template <typename T1, typename T2>
U>std::pair<T1, T2> make_pair(T1 t1, T2 t2) {
U>    return std::pair<T1, T2>(t1, t2);
U>}
U>


А почему в 03 по значению стали передавать??
Re: эволюция std::make_pair
От: Кодт Россия  
Дата: 10.09.14 07:52
Оценка:
Здравствуйте, uncommon, Вы писали:

U>C++14

U>
U>std::pair<std::decay_t<T1>, std::decay_t<T2>>
U>


О как! Шаблонные typedef'ы на марше. К этому ещё надо привыкнуть...

U>C++17?


Для распространённого производного типа decay_t<T> можно было бы ввести и оператор, скажем, T~ (в суффиксной форме, чтобы не выбиваться из общего ряда)
template<class T1, class T2>
constexpr
std::pair<T1~, T2~>
make_pair(T1&& t1, T2&& t2)
{
  return std::pair<T1~,T2~>(t1,t2);
}
Перекуём баги на фичи!
Re[2]: эволюция std::make_pair
От: uzhas Ниоткуда  
Дата: 10.09.14 08:18
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Для распространённого производного типа decay_t<T> можно было бы ввести и оператор, скажем, T~ (в суффиксной форме, чтобы не выбиваться из общего ряда)


оператор над типом? не C++ — way =\
Re[3]: эволюция std::make_pair
От: Кодт Россия  
Дата: 10.09.14 09:09
Оценка:
Здравствуйте, uzhas, Вы писали:

К>>Для распространённого производного типа decay_t<T> можно было бы ввести и оператор, скажем, T~ (в суффиксной форме, чтобы не выбиваться из общего ряда)


U>оператор над типом? не C++ — way =\


Что это не вей? Очень даже вей.
T* и T& — биективные, T const и T volatile — сюръективные, T&& — от контекста зависит (может трактоваться как обобщённая ссылка).
И паттерн-матчинг на них работает, невзирая на сюръективный характер cv-квалификаторов. (T const const = T const, т.е. обратное отображение инъективно).
Перекуём баги на фичи!
Re[4]: эволюция std::make_pair
От: uzhas Ниоткуда  
Дата: 10.09.14 10:50
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Что это не вей? Очень даже вей.

К>T* и T&
ах вот с какой колокольни надо смотреть, тут согласен, есть куда расширяться

К> — биективные, T const и T volatile — сюръективные, T&& — от контекста зависит (может трактоваться как обобщённая ссылка).

ну тут я вообще не смог убедиться в биективности\сюръективности\инъективности. как-то оно не сходится: снять ссылку или указатель не с любого типа можно и не все типы имеют const, к примеру.
к тому же у этих "операторов" разные области определения

К>И паттерн-матчинг на них работает

по крайне запутанным правилам
в целом, ты пытаешься натянуть строгую теорию на нестрогий и кривой C++. это заведомо провальный план =)
Re: эволюция std::make_pair
От: zaufi Земля  
Дата: 10.09.14 11:19
Оценка:
Здравствуйте, uncommon, Вы писали:

U>Такая маленькая функция. Что может быть проще? (по мотивам vimeo.com/97337253)


U> C++14:

интересно почему return type не auto???

template <typename T1, typename T2>
constexpr
auto
make_pair(T1 && t1, T2 && t2) {
    return std::pair<std::decay_t<T1>, std::decay_t<T2>>(std::forward<T1>(t1), std::forward<T2>(t2));
}
Re[5]: эволюция std::make_pair
От: Кодт Россия  
Дата: 10.09.14 12:24
Оценка: +1 :)
Здравствуйте, uzhas, Вы писали:

К>> — биективные, T const и T volatile — сюръективные, T&& — от контекста зависит (может трактоваться как обобщённая ссылка).

U>ну тут я вообще не смог убедиться в биективности\сюръективности\инъективности. как-то оно не сходится: снять ссылку или указатель не с любого типа можно и не все типы имеют const, к примеру.
U>к тому же у этих "операторов" разные области определения

Согласен, нагнал лишнего с формализмами. Суть в том, что некоторые операции однозначно-обратимые, а другие нет.

Можно считать, что операция, обратная наложению указателя/ссылки, применительно к не-указателю/не-ссылке даёт тип "substitution failure"... а можно и не считать.
Глубоко в теорию типов никогда не втыкал, какой там формализм для этого предусмотрен, врать не буду.
Вот, а операция снятия константности применительно к неконстантному типу даёт (тот же) тип.

К>>И паттерн-матчинг на них работает

U>по крайне запутанным правилам

Запутанность там связана лишь с тем, что у нас перемешаны алгебраические типы и типы, приводимые друг к другу несколькими разными способами.

Для начала, можно считать, что T~ это просто короткая запись для decay<T>::type

Следующим шагом — определить правило вывода, подобное T&&
— в списке параметров шаблона к T~ матчится только T, то есть, мы говорим "здесь должен быть уже очищенный тип, безо всяких этих ваших const-shmonst"
— в списке аргументов функции типы T, T&, T&&, T const, T const& матчатся к T~
— из всех их получается T

(Понятно, что в случае template typedef такой фокус в принципе невозможен, т.к. зависимые имена не выводятся)

U>в целом, ты пытаешься натянуть строгую теорию на нестрогий и кривой C++. это заведомо провальный план =)


План работает уже четвёртый десяток лет.
Ад хок, но это наш ад хок.
Перекуём баги на фичи!
Re[2]: эволюция std::make_pair
От: UA Украина  
Дата: 10.09.14 16:02
Оценка:
J>А почему в 03 по значению стали передавать??

Решили что пользователям пришло время проапгрейдится на новое железо.
Re[2]: эволюция std::make_pair
От: uncommon Ниоткуда  
Дата: 10.09.14 22:43
Оценка: 20 (3) :)
Здравствуйте, Jack128, Вы писали:

J>А почему в 03 по значению стали передавать??


http://cplusplus.github.io/LWG/lwg-defects.html#181

Как там написано, при передаче строкового литерала в "T const &", T получает тип массива char[N], а это некопируемый тип
Re: эволюция std::make_pair
От: landerhigh Пират  
Дата: 11.09.14 20:39
Оценка:
Здравствуйте, uncommon, Вы писали:

Да уж... вот как покажется, что вроде знаешь C++ с потрохами, так ан нет.. именно что кажется
www.blinnov.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.