LINUX.ORG.RU

Какое же говнище этот ваш С++

 


11

7

Решил намедни углубить свои знания по плюсам, чувствуя, что скоро нехило так потребуются по работе. Теперь сижу, обмазываюсь тут всякими трупами страусов, Скоттом Майерсом и другими. Г-пди, как же можно на этом писать, особенно после знания божественных лиспов, хаскелей и прочих матанских агд (sic!). Это какая-то пытка, честное слово, мне натурально мерзко и противно читать как люди пытаются вырезать гланды через задний проход да ещё и хвалятся этим, поглядите, мол, как это круто. Такое ощущение, будто плюсисты все поголовно латентные мазохисты.

template <typename T>
class Rational
{
    public:
    ...
    friend const Rational operator*(const Rational& lhs, const Rational& rhs)
    {
        return Rational(lhs.numerator() * rhs.numerator(), // same impl
            lhs.denominator() * rhs.denominator()); // as in Item 24
    }
}

An interesting observation about this technique is that the use of friendship has nothing to do with a need to access non-public parts of the class. In order to make type conversions possible on all arguments, we need a non-member function (Item 24 still applies); and in order to have the proper function automatically instantiated, we need to declare the function inside the class. The only way to declare a non-member function inside a class is to make it a friend. So that's what we do. Unconventional? Yes. Effective? Without a doubt.

Нафиг так жить, почему нельзя всё было сделать по-человечески, как в нормальных языках? Ненавижу страуса, ненавижу плюсы, ненавижу тех идиотов, которые упорно продолжают куда ни попадя совать этот мёртвородженный язычок. И ниасилил, да.

Перемещено mono из talks

★★★★★

Последнее исправление: mono (всего исправлений: 1)

Ответ на: комментарий от cab

У меня одного ощущение, что с дизайном то ли сигнатуры, толи генериков что-то явно не того

На самом деле подобное будет в любом языке со статической типизацией, если программист дурак.

mix_mix ★★★★★
() автор топика
Ответ на: комментарий от wota

людям надо в рантайме - Java не может

Ты хоть чуть чуть бы санити чек перед тем как такие заявления бы делал?

ArrayUtils.reverse

r ★★★★★
()
Ответ на: комментарий от r

Ты хоть чуть чуть бы санити чек перед тем как такие заявления бы делал?
ArrayUtils.reverse

LOL, второй подряд «шедевр» от тебя после перебора мапы

wota ★★
()
Ответ на: комментарий от r

Это никому не нужно на стадии компиляции.

Да неужели? :)

Благодаря таким возможностям метапрограммирования на С++ (сортировка и поиск) можно решать простенькие задачи оптимизации на стадии компиляции декларативных объявлений. Очень полезная вещь, если уметь ею пользоваться.

aist1 ★★★
()
Ответ на: комментарий от aist1

Благодаря таким возможностям метапрограммирования на С++

А можно увидеть реализацию сортировки на шаблонах?

mix_mix ★★★★★
() автор топика
Ответ на: комментарий от aist1

можно решать простенькие задачи оптимизации на стадии компиляции декларативных объявлений

В смысле сортировки константных значений? Очень очень полезная фича.

Вот частичные вычисления времени компиляции в общем виде - это хорошее направление развития компиляторов - собственно ее Александреску и пытался хоть как-то решить. Но шаблоны тут опять же - не разумное спланированное средство с возможными перспективами развития - а хрень которую применяют не по назначению. Вроде книжки по физике под ножкой пианино. И то что хоть как то работает - не обозначает что так и надо. Это так же перспективно как печатать книжки по физике чтобы ими подпирали пианино.

r ★★★★★
()
Ответ на: комментарий от aist1

Да, только код далеко не идеален.

Он не просто не идеален - он злобно ужасен в принципе. Абстрагируйся от того что это шаблоны и плюсы и рассмотри задачу абстрактно - простая задача сортировки массива. Что ты скажешь об языке где массив сортируется вот таким кодом?

r ★★★★★
()
Ответ на: комментарий от r

Что ты скажешь об языке где массив сортируется вот таким кодом

Ты что там, qsort ожидал увидеть? Если ты не в курсе, шаблонное метапрограммирование в С++ функциональное. Ты не можешь взять и «поменять значения ячеек».

Кроме того, там нет массивов. Там списки. В конце-концов, для больших списков этот метод всё равно не предназначен.

Если ты хочешь сказать, что метопрограммирование в С++ очень неудобно синтаксически и ограничено в выразительности конструкций, то сенсации не сделаешь. Я даже с тобой соглашусь. Есть такая проблема.

Но, хоть и через «твоюмать», и через кровь с потом, метапрограммирование в С++ свое дело делает. Массив сортируется. У меня, например, есть статический MD5. Используется подсистемой сериализации для вычисления хэш-кодов объектов во время их компиляции. Сначала я думал, что сделаю его так, на посмотреть. Оказалось, отлично работает. Оставил.

Тебе шашечки или ехать?

aist1 ★★★
()
Ответ на: комментарий от aist1

Ты что там, qsort ожидал увидеть?

Я там как раз это и ожидал увидеть. Только не надо доказывать что вот это - хорошо и правильно.

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

А иначе оно не может быть. Без чистоты доказанной чистоты или вычисленных эффектов это не сработает.

Но, хоть и через «твоюмать», и через кровь с потом, метапрограммирование в С++ свое дело делает.

Как и книжка по физике. Только это тупиковый путь. Так _не надо_ делать в смысле развития языков.

Тебе шашечки или ехать?

Для ехать - книжка по физике под пианино работает. Для дискусси вида «правильные направления развития ремонтного дела пианин» - это не вариант. Развивать «вычислимость» шаблонов для md5 времени компиляции - дело бесперспективное. А вот развивать частичные вычисления времени компиляции для основного языка - дело почетное.

r ★★★★★
()
Ответ на: комментарий от r

Только не надо доказывать что вот это - хорошо и правильно.

Я и не буду. В данном случае иначе было бы не сделать.

А иначе оно не может быть. Без чистоты доказанной чистоты или вычисленных эффектов это не сработает.

Что не сработает? Метапрограммирование? Почему? Не мог бы ты раскрыть мысль?

Так _не надо_ делать в смысле развития языков.

Это давно уже признали и пытаются ситуацию исправить, на сколько это реально теперь. Не ломая уже сложившуюся парадигму.

частичные вычисления времени компиляции

Не мог бы ты это на английский перевести?

aist1 ★★★
()
Ответ на: комментарий от alienclaster

У него нет никакой области после появления например RoR, т.е. вообще никакой.

Не надо, не надо тут. Вот пристанете вы со своими фреймворками сраными, где всё косо криво, и шаг в сторону = побег... Ручками писать под веб, между прочим, на пыхе куда удобнее, чем где бы то ни было. И быстрее он питона раза в 2, а руби - раза в 4. Ну т.е. сам как язык, что с учётом работы с БД ты, понятное дело, не заметишь. И синтаксис у него более приятный, «традиционный» C-подобный. И вообще у меня такое подозрение, что если начать исправлять недостатки perl5, не изобретая perl6 - получится просто ещё один php.

По теме треда: тред ржачный, но поддерживаю всех. И тех, кто C++ обсирает, и тех, кто говорит «вы просто не умеете его готовить». Когда я ещё маленький был и первый раз в книжках по C++ прочитал про шаблоны, сразу подумал, что писать код в заголовочных файлах - это какой-то **аный маразм и отстой. А так, без шаблонов C++, в принципе, почти нормальный язык. ;)

Однако, похоже, что все, кто до сих пор на нём пишет, шаблонами прониклись, а остальные просто вымерли / перешли на другие языки. И теперь эти проникшиеся считают, что кто STL и boost в 10 этажей не юзает - лошара. ;) А Тролльвардс вот например считает что C++ кодеров до ядра допускать нельзя. ;)

... но и автор треда, конечно, тоже молодец. Даже не учитывая то, что указатели сортировать нужно было, а не значения, сама идея интересная - «что-то у меня qsort тормозит, давайте я его в волшебном C++ заюзаю и он уже от этого действия должен стать быстрее!» ))

vitalif ★★★★★
()
Последнее исправление: vitalif (всего исправлений: 3)
Ответ на: комментарий от aist1

Что не сработает? Метапрограммирование? Почему? Не мог бы ты раскрыть мысль?

Метапрограммирвоание - это очень общее слово. Вычислимость шаблонов. Если бы они не были инвариантны и вычислимы полностью - ничего бы не сработало. Если бы там можно было создать гонки или невычислимые эффекты во внешнюю память - компилятор не мог бы их вычислять в ноль однозначно. То по простому - эту программу компилятор должен иметь возможность выполнить с однозначными результатами. А следовательно она не может зависеть от внешней среды.

Не мог бы ты это на английский перевести?

http://dlang.org/function.html#interpretation

r ★★★★★
()
Ответ на: комментарий от r

Метапрограммирвоание - это очень общее слово. Вычислимость шаблонов.

Я вижу, ты просто не в теме. Это нормально. Метопрограммирование — это когда программа пишет программу. С помощью шаблонов или другого метода - не важно. В С++ метопрограммирование возможно только с помощью шаблонов во время компиляции (варианты динамических компиляторов и интерпретаторов С++ я здесь не учитываю). В Java метапрограммирование осуществляется с помощью BCI в рантайме, без какой либо функциональщины. В Скале есть еще макросы, выполняющиеся во время компиляции и работающие с AST. Я не знаю, на сколько они должны быть чистыми.

То по простому - эту программу компилятор должен иметь возможность выполнить с однозначными результатами.

Это имеет смысл только для макросов и других функций времени компиляции. Ко всему метапрограммированию это требование не относится.

http://dlang.org/function.html#interpretation

Спасибо, теперь понял. В С++14 будут такие функции. Там даже можно будет быстро отсортировать массив чисел. Но не список типов :)

Я хотел бы в С++ иметь еще и макросы лиспа/скалы.

aist1 ★★★
()
Ответ на: комментарий от aist1

Метопрограммирование — это когда программа пишет программу.

Очевидно.

Я не знаю, на сколько они должны быть чистыми.

Вот именно. Поэтому говорить что система должна быть чистой в смысле чистоты функций в метапрограммировании вообще - некорректно - потому что это не так. А в данной конкретной ситуации с с++ шаблонами - они должны быть чистыми.

Это имеет смысл только для макросов и других функций времени компиляции

Мы говорим о темплейтах с++.

В С++14 будут такие функции.

Не такие. constexpr это совсем не то. Это как раз еще одна наполовину сделанная работа. Список ограничений там такой мрачный что это будет совсем отдельный класс «специальных константных» функций. В D такого нету. Там любая практически функция может быть вычислена если она практически вычислима во время компиляции. Никаких специальных телодвижений для их разметки делать не нужно.

r ★★★★★
()
Ответ на: комментарий от r

А в данной конкретной ситуации с с++ шаблонами - они должны быть чистыми.

Я понял твою мысль. Да, согласен. Спасибо за разъяснение :)

Список ограничений там такой мрачный что это будет совсем отдельный класс «специальных константных» функций.

Совсем не такой уж и мрачный.

C++14 will relax these restrictions. Constexpr-declared functions may now contain the following:
    Any declarations except:
        static or thread_local variables.
        Variable declarations without initializers.

    The conditional branching statements if and switch. goto is not allowed.
    
    All looping statements, including range-based for.
    
    Expressions may change the value of an object if the lifetime of that object began within the constant 
    expression function. This includes calls to any non-const constexpr-declared non-static member functions.

Из заметных ограничений только необходимость всегда указывать constexpr, если ф-я может вызываться компилятором. Ну..., стандартная библиотека будет поправлена соответствующим образом.

В D такого нету.

Это да. constexpr выглядит излишним. Но ехать можно, хоть и без шашечек.

aist1 ★★★
()
Последнее исправление: aist1 (всего исправлений: 1)
Ответ на: комментарий от r

В D такого нету. Там любая практически функция может быть вычислена если она практически вычислима во время компиляции. Никаких специальных телодвижений для их разметки делать не нужно.

и никаких гарантий, что это действительно compile time evaluation тоже нет, т.к. всего одна строчка в одной из вызываемых функции тихо и незаметно уберет данную оптимизацию, что в корне убивает саму идею и превращает все в «где-нибудь компилятор с подсказкой может быть сможет оптимизировать», а это современные компиляторы и так умеют и без подобных подсказок

wota ★★
()
Ответ на: комментарий от r

Твое решение в студию?

для Java? не вижу смысла пытаться на ней что-то решать, если даже ее фанаты на ней не могут прямо решить задачу в одну строку

wota ★★
()
Ответ на: комментарий от wota

и никаких гарантий, что это действительно compile time evaluation тоже нет, т.к. всего одна строчка в одной из вызываемых функции тихо и незаметно уберет данную оптимизацию...

Все определения функций должны быть доступны компилятору. И он всё равно будет проверять выполнение ограничений. Тут r прав по сути, constexpr выглядит излишним. Надо спрашивать дизайнеров языка, в чем его сакральный смысл, кроме неочевидного структурирования кода.

aist1 ★★★
()
Ответ на: комментарий от aist1

Все определения функций должны быть доступны компилятору. И он всё равно будет проверять выполнение ограничений. Тут r прав по сути, constexpr выглядит излишним. Надо спрашивать дизайнеров языка, в чем его сакральный смысл, кроме неочевидного структурирования кода.

да - компилятор может и так соптимизировать подобное, но, если ты действительно хочешь, чтоб это было compile time - ты сообщаешь об этом компилятору, и он проверяет, и в случае чего выдает тебе ошибку, а не молча пропускает; точно так же и обычный const - компилятор может проверить, что данное значение не будет меняться, ты тоже можешь так предполагать, но, явно указав const, ты просишь компилятор делать проверку и в случае чего сообщать тебе

wota ★★
()
Ответ на: комментарий от wota

Понимаешь, const нужен, потому что функции, с ним объявленные, могут быть недоступны на момент компиляции, а доступны только на момент линковки. И проверить их не представляется возможным.

С constexpr не так. Определение функции всё равно должно быть доступно на момент компиляции. Она всё равно проверяется.

aist1 ★★★
()
Ответ на: комментарий от aist1

Понимаешь, const нужен, потому что функции, с ним объявленные, могут быть недоступны на момент компиляции

а я то дурак думал, что const нужен для другого...

wota ★★
()
Ответ на: комментарий от wota

Ты не понял. Я говорил, что объявление const необходимо указывать явно по крайней мере для функций-членов, потому что их определение может быть недоступно во время компиляции. И проверить его, а действительно ли эта ф-я ничего не меняет, в этом случае нельзя.

aist1 ★★★
()
Последнее исправление: aist1 (всего исправлений: 1)
Ответ на: комментарий от wota

т.к. всего одна строчка в одной из вызываемых функции тихо и незаметно уберет данную оптимизацию

И убирает она не функцию а путь исполнения. Если компилятор может частично вычислить - он это сделает. Это ж не фетишизм «обязательно времени компиляции». Это вот именно оптимизация.

r ★★★★★
()
Ответ на: комментарий от r

Это ж не фетишизм «обязательно времени компиляции»

да - это чисто практическая выгода при работе программы

Это вот именно оптимизация.

а в таком виде тот же gcc и так делал оптимизацию

wota ★★
()
Ответ на: комментарий от r

На чем угодно.

ну если говорить именно про массивы и именно int:

sort( a.begin(), a.end(), greater<int>() );

ну или для сишных:

sort( a, a + n, greater<int>() );
wota ★★
()
Ответ на: комментарий от wota

тут опять же можно поругать STL, можно было бы сделать и:

sort( a, greater );
wota ★★
()

Какое же говнище этот ваш С++

Да.

gensym ★★
()
Ответ на: комментарий от wota

ну если говорить именно про массивы и именно int:

Ну и что тебе не нравится в жабском решении?

r ★★★★★
()
Ответ на: комментарий от r

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

А иначе оно не может быть. Без чистоты доказанной чистоты или вычисленных эффектов это не сработает.

ну и где именно в плюсах «доказанная чистота» (или, хотя бы на уровне строго проверямых деклараций) и контролируемые вычисляемые эффекты (типа монад)?

anonymous
()
Ответ на: комментарий от r

А вот развивать частичные вычисления времени компиляции для основного языка - дело почетное.

А почему именно для 'основного языка'? А то специальной олимпиадой попахивает.

anonymous
()
Ответ на: комментарий от aist1

частичные вычисления времени компиляции

Не мог бы ты это на английский перевести?

partitial evaluation, compile-time function execution, multi-stage partitial evaluation, supercompilation

anonymous
()
Ответ на: комментарий от aist1

Я хотел бы в С++ иметь еще и макросы лиспа/скалы.

проще наоборот.

anonymous
()
Ответ на: комментарий от wota

всего одна строчка в одной из вызываемых функции тихо и незаметно уберет данную оптимизацию, что в корне убивает саму идею и превращает все в «где-нибудь компилятор с подсказкой может быть сможет оптимизировать»,

Вообще так не делается. Пишется функция, результат которой выводится прагмой pragma message . Это как бы гарантирует нам, что она вычислится именно во время компиляции. Потом аналогичным образом — запускаются юнит-тесты для ctfe-функций. Если ВНЕЗАПНО что-то сломалось, то прагма не отработает, и это сразу будет видно.

Да, в текущей реализации CTFE ещё есть над чем поработать (не все функции доступны, и есть ограничение на размер стека). Но а) над этим работают; б) в С++ всё ещё хуже — ничего нельзя гарантировать.

anonymous
()
Ответ на: комментарий от wota

если ты действительно хочешь, чтоб это было compile time - ты сообщаешь об этом компилятору, и он проверяет, и в случае чего выдает тебе ошибку, а не молча пропускает;

Зачем? Достаточно умный компилятор может это сам вывести.

Ах ну да, вы же хинт оптимизатору типа 'virtual' тоже привыкли ручками указывать, у вас же нет 'достаточно умного компилятора'

точно так же и обычный const - компилятор может проверить, что данное значение не будет меняться

не может в плюсах, потому что там константность нетранзитивна. Чем и отличается constness/immutability в D.

anonymous
()
Ответ на: комментарий от aist1

потому что функции, с ним объявленные, могут быть недоступны на момент компиляции, а доступны только на момент линковки.

ну и что?

И проверить их не представляется возможным.

если

а) побочные эффекты таких функций строго контролируются и ограничены

б) всё, что они могут сделать на момент комплияции — это дёргать рантайм языка и компилятора

в) есть гарантия, что не зациклимся

то проверять и не надо.

anonymous
()
Ответ на: комментарий от r

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

Где именно в плюсах гарантируется?

То же самое про immutability и транзитивность константности.

anonymous
()
Ответ на: комментарий от anonymous

Где именно в плюсах гарантируется?

В шаблонах. Мы про них.

r ★★★★★
()
Ответ на: комментарий от r

Это ж не фетишизм «обязательно времени компиляции». Это вот именно оптимизация.

обязательно, при соблюдении некоторых условий.

anonymous
()
Ответ на: комментарий от anonymous

Это как бы гарантирует нам

это просто хак, причем с побочными эффектами

в С++ всё ещё хуже — ничего нельзя гарантировать.

1.cpp: In function ‘constexpr int foo()’:
1.cpp:5:14: error: call to non-constexpr function ‘int rand()’
  return rand();
wota ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.