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)

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

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

Не понял, а в чем таки проблема то? В математике операция умножения матрицы на вектор не эквивалентна операции умножения кватерниона на кватернион. Некоторые говорят ну её, эту математику, лучше филологию изучать. Давайте от математики откажемся?

Причём эта зависимость нигде(кроме какого-то кода) не прописана и не документирована

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

ckotinko ☆☆☆
()
Ответ на: комментарий от mix_mix

Половина или «нинужна», или нужно для построения «монадического стека приложения», «но это уже проблемы идеологии», то есть в C++ принципиально не заводится (или это будет уже не C++).

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

Т.е. без Си++ - никуда %)

Без ассемблера тоже никуда. Но логику на нем никто не пишет.

Пойнт был в том, что «основной язык» всё равно C-based.

Objective-C определенно основан на Си, про Java и C# такое сказать сложно.

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

Без ассемблера тоже никуда.

Глупости.

Objective-C определенно основан на Си, про Java и C# такое сказать сложно.

«Наша песня хороша, начинай сначала» (ц)

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

На какие только извращения не приходится идти, когда макросов нет.

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

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

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

потому это там зашивается в компилятор

Вот если бы std::function тоже зашивался в компилятор, то target бы всегда работал — для callback-ов в сишный код было бы удобно, тем более у gcc всё что нужно для этого есть (работает для nested functions).

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

В C++ свободы слишком много.

ну и отлично. никто ж не призывает сразу все фичи использовать. можно просто их не использовать и всё. гораздо удобнее использовать простой класс чем структуру и кучу методов. RAII гораздо удобнее, чем ручное управление мутексами и прочими ресурсами. готовые map и unordered map удобнее, чем велосипедостроение.

поэтому те, кто утверждают что си круче с++ -это рукожопы. никогда не писавшие ничего серьезного даже на си.

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

ckotinko ☆☆☆
()
Ответ на: комментарий от note173

Интересно, а в коде Cocoa и Quartz преобладает код на чистом ObjC, или там смесь, где основа на Си/Си++, а оболочка уже на ObjC?

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

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

Или не придется, если уже есть интринсики.

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

И даже те, которым они реально нужны, обычно с ассемблером не связываются.

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

никто ж не призывает сразу все фичи использовать. можно просто их не использовать и всё

Если не использовать фичи C++ то получается С, чего ты доказать пытаешься ?

никогда не писавшие ничего серьезного даже на си.

Да тут сплошные «светилы» собрались, вас же без смеха читать невозможно.

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

А, вижу сейчас, что у них для частей на ObjC используются другие префиксы.

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

Интринсики не всесильны и все равно платформенно зависимы.

Интринсики - это не ассемблер, и даже они нужны для узкого класса вычислений.

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

А я правильно понимаю, что от опционального GC (сборка мусора в стиле Java) могут совсем отказаться в будущих версиях ObjC, даже для OS X? Знаю, что раньше она точно не поддерживалась на iOS, может быть, и сейчас не поддерживается.

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

Если не использовать фичи C++

Если не использовать __все__ фичи C++

если не уметь читать написанное, то получается дэбил.

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

Да тут сплошные «светилы» собрались,

Ну да, Enterprise программеры 80-го левела.

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

если не уметь читать написанное, то получается дэбил.

Ты и есть упоротый дебил, рассуждаешь о том в чем ничего не понимаешь

чем сишный код легче для понимания, чем с++ с классами, но без шаблонов?

В С как раз и не хватает шаблонов, в GCC специально для разработки ядра расширение стандарта (typeof) ввели для обобщенных алгоритмов.

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

гораздо удобнее использовать простой класс чем структуру и кучу методов.

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

готовые map и unordered map

... а так же куча специализированных контейнеров от сторонних разработчиков, включая Boost.Multiindex

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

просто не пиши на с++, если шило в жопе не дает писать нормальный код. неосилятор

ckotinko ☆☆☆
()
Ответ на: комментарий от yoghurt

А ви таки хотели бы, чтобы деструктор X в этом случае не вызывался?

Ми таки знаем что он не вызывается. И таки показываем что исключения в плюсах... «очень внимательно».

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

гораздо удобнее использовать простой класс чем структуру и кучу методов.

Вообще-то эти подходы изоморфны (как x(l) и l(x) в линале)

Нахрена нам какие-то там удобства, проверки типов компилятором... изоморфизм - наше всё.

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

. В плюсах по историческим причина то

А я что говорю? Сплошные исторические причины, наследие и т.д.

Но это просто дефолт, и хороший тон перезагружать конструктор копий и оператор копирования.

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

Да - про это ия и говорю. Можно писать - если сам всем рулишь. о мы про большие проекты не?

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

я тебе привёл пример, что в C++ ты можешь сделать _свой_ Integer

Ты наверное не понимаешь что такое бедная система типов....

если-бы оно было нормально написано

если бы оно было нормально написано оно бы решало проблемы программиста а не требовало чтобы оно было «нормально написано».

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

неосиляторы жалуются на то, что пишут говнокод

Вот это типичный ответ человека которому нравится осваивать ипонутый инструмент. Все нормальныё люди пользуются и создают вменяемые инструменты, потому что делают так чтобы проблема не возникала вообще никогда, и создают инструменты которыё этому способствуют, а не страдают херней.

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

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

ckotinko ☆☆☆
()
Ответ на: комментарий от quasimoto

если честно, то я не понял где оно надо, и как собрать, чтобы поиграться с этим подробнее.

Нормальные как раз в С++ :) Т.е. индексация любыми числами, enum-ами и вообще объектами (если делать ссылки на constexpr).

нормальные относительно текущих решений в haskell, там нормальный констрейнт солвер будет.

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

Спасибо за ответы! Просто присматриваюсь к платформе. Похоже, что все, что не Cocoa, выглядит на маке как-то не очень.

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

А, проглядел порядок true/false. Однако смартпоинтер здесь бы помог.

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

если честно, то я не понял где оно надо, и как собрать, чтобы поиграться с этим подробнее.

Ну собрать c++ -std=c++11 file-name.cc && ./a.out — оно должно написать, что sizeof(short) для a и sizeof(int) для b и c, то есть decltype для auto c выберет типом S<B>, то есть из A (~ short) и B (~ int) в качестве sup возьмёт B, S<B> c2 скомпилируется, S<A> c3 — нет, в итоге при сложении матриц с элементами разного типа результирующая матрица всегда будет иметь типом элемента тип который достаточен (sup) для отсутствия переполнения (кроме своего собственного).

нормальные относительно текущих решений в haskell

haskell

*GHC. Надеюсь, будет так же естественно как и std::array и т.п.

Индексация по числовому типу:

// concat : {T : Type, a b : Size} -> Array T a -> Array T b -> Array T (a + b)
template <typename T, size_t a, size_t b>
std::array<T, a + b> concat(std::array<T, a> const& x, std::array<T, b> const& y) {
    std::array<T, a + b> z;
    std::copy(x.begin(), x.end(), z.begin());
    std::copy(y.begin(), y.end(), z.begin() + x.size());
    return z;
}

    std::array<int, 3> x = {{1, 2, 3}};
    std::array<int, 2> y = {{4, 5}};
    auto z = concat(x, y); // std::array<int, 5>

По enum-у:

enum class abc { a = 1, b, c };

// foo : {abc} -> R
template <abc> R foo();
template <> R foo<abc::a>() { ... }
template <abc bc> R foo() { ... bc ... }

По числовому типу и объекту-массиву с зависимостью в сигнатуре:

// bar {rank : Size, sizes : Array Size rank} : Type
template<size_t rank, std::array<size_t, rank>& sizes>
struct bar {
    ...
};

extern std::array<size_t, 3> s;
std::array<size_t, 3> s = {{1, 2, 3}};

    bar<3, s> a;

хотя тут уже немного криво, так как нужно обеспечивать постоянство адреса s.

Пока я не знаю как такие вещи нормально в хаскеле делать.

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

Вот такой аналог придумался:

{-# LANGUAGE MultiParamTypeClasses, TypeFamilies #-}

class Mono a b where
  mono :: a -> b

instance Mono Int Integer where
  mono = toInteger

instance Mono Integer Integer where
  mono = id

-- ... over100500 instances

type family Sup a b :: *

type instance Sup Int Integer = Integer

-- ... again

data Matrix a = Matrix a

(<+>) :: (Num c, c ~ Sup a b, Mono a c, Mono b c) => Matrix a -> Matrix b -> Matrix c
Matrix x <+> Matrix y = Matrix (mono x + mono y)

-- Matrix (1 :: Int) <+> Matrix (2 :: Integer) :: Matrix Integer

vs

template <typename A>
struct Matrix {
    A value;
    /* explicit? */ Matrix(A const& value_) : value(value_) {}
    template<class B>
    friend Matrix<decltype(A() + B())> operator+(Matrix const& x, Matrix<B> const& y) {
        return /* no conv? */ x.value + y.value;
    }
};

    auto x = Matrix<int>(1) + Matrix<double>(2);
    // ^ Matrix<double>

за счёт того что operator+ не мономорфный и берёт на себя проведение вложений (в лучшем случае, конечно).

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

Основная задача аллокаторов - решать проблему фрагментации в долгоживущих програмах написаных на плюсах (и си). Плюсовые проблемы.

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

И да, основная задача кастомных аллокаторов все-таки в том, чтобы увеличить скорость выделения памяти, но в этими ваших managed-языках пытаться оптимизировать работу кучи вообще бесполезно.

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

Хаскель. У ерланга динамическая типизация.

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

Так всё-так что лучше - хаскель или ерланг?

Лисп.

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

Да тут сплошные «светилы» собрались, вас же без смеха читать невозможно.

o2n3e, ты опять резвишься в бане с травой? Читатель ждет уж слова «днище». Давай, скажи его скорей.

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

Или что в них из-за особой уличной магии не фрагментируется память?

Представь себе. Эта уличная магия называется.... GC!

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

Они что по твоему RAS/CAS-магию делают чтоле ? Почему по твоему выделение памяти тормозит? Изза этой самой фрагментации - трудно найти подходящий кусок. Со временем работы фрагментация возрастает. Поэтому аллокаторы в основном занимаются пулингом памяти для объектов одного типа.

но в этими ваших managed-языках пытаться оптимизировать работу кучи вообще бесполезно.

facepalm. Ее там оптимизирует GC, при чем делает это лучше чем аллокаторы. Гуглить heap compaction.

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

Например большие проекты. Там где используются десятки сторонних библиотек и фреймворков. Ах да - такого в мире с++ почти не бывает - именно потому определенный класс софта там и методики разработки наборов либ там практически отсутствуют, а большие проекты вроде Qt пишут абсолютно все свое.

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

Там где используются десятки сторонних библиотек и фреймворков.

десятки

Для чего? Для подпорок под несопровождабельным говном из других велосипедов, с пересекающейся функциональностью, которой юзерам не хватает в каждом из отдельно взятых фреймворков - дельфи-стайл? Ты конкретней давай, что ли. Пример проекта с десятками фреймворков (список прилагается - заодно посчитаем :)) Или, например, балабол, сферический в вакууме про сферические в вакууме большие проекты :)

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

В сишечке попроще, ибо там ты видишь функцию, и по её прототипу знаешь, что у неё на входе.

Ато O_o void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*)); Все ясно, void void-ом погоняет.

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

Работу GC невозможно контролировать из кода, что и делает невозможной ручную оптимизацию. Против неоптимизированного С++-кода GC может дать лучший результат, но по сравнению с кастомным аллокатором сольет все равно.

Почему по твоему выделение памяти тормозит? Изза этой самой фрагментации - трудно найти подходящий кусок.

Еще из-за количества этих кусков. Если ты знаешь, что в течение работы приложения понадобится выделить стопицот объектов фиксированного размера, ты создаешь пул для них и постепенно его заполняешь. Никакой умный GC не сможет предсказать этот сценарий без libastral.

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

Не понял, а в чем таки проблема то? В математике операция умножения матрицы на вектор не эквивалентна операции умножения кватерниона на кватернион.

да. Но в математике умножение не может ВНЕЗАПНО стать кирпичом, оно всегда останется умножением, которое конечно зависит от того, что на что множат. А вот в C++ — да пожалуйста. В этом-то и проблема.

Некоторые говорят ну её, эту математику, лучше филологию изучать. Давайте от математики откажемся?

некоторые здесь говорят тоже самое про C++. И мне нечего им возразить. Пусть изучают философию, я не против.

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

зачем в документации расписывать детали реализации? Не нужно. Да и никто так не делает. Проблема в том, что для того, что-бы Линусу или его соратникам принять какой-то патч, в детали вникнуть таки надо. Ну вот Линус и не любит C++. Мне это вполне понятно.

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

Если ты знаешь

вернее, ты создаешь такие условия сам, чтоб не париться о предсказаниях :)

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

ну и отлично. никто ж не призывает сразу все фичи использовать. можно просто их не использовать и всё.

это понятно. Просто наш r пытается использовать известные ему фичи там, где они неуместны. И обижается, что «медленно».

гораздо удобнее использовать простой класс чем структуру и кучу методов.

не совсем так. Если класс хорошо продуман, то ты безусловно прав, но если класс криво спроектирован, то уж лучше-бы он был написан на ассемблере!

RAII гораздо удобнее, чем ручное управление мутексами и прочими ресурсами. готовые map и unordered map удобнее, чем велосипедостроение.

поэтому те, кто утверждают что си круче с++ -это рукожопы. никогда не писавшие ничего серьезного даже на си.

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

ППКС.

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

Если не использовать фичи C++ то получается С, чего ты доказать пытаешься ?

в C++ очень много фич. Это не только классы и шаблоны.

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

если класс криво спроектирован, то уж лучше-бы он был написан на ассемблере!

Нетъ, на С лучше, иначе у меня под SH4 не соберется.

annulen ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.