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)
Ответ на: комментарий от r

Меня не глубина генериков беспокоит а невменяемые ошибки развернутых темплейтов которые резолвить - отдельный двинутый скилл.

Именно эту беду можно считать почти решенной при использовании clang. Сейчас препятствием являются не шифрованные сообщения об ошибках, а отсутствие концептов. Частично компенсируется наличием static_assert. Т.е. существовать (решать задачи) можно. Но не жить.

Нужны модули, концепты, репозитарии библиотек, инструменты работы с кодом — и экосистема С++ начнет потихоньку догонять экосистему Java.

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

то не комилируемо раз

Ну можно заменить auto в лямбде на явный тип. Или использовать класс-функтор :)

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

то не комилируемо раз

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

Там перекладывание идет в какие-то хитрые мапы.

да не суть важно в какие

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

Да - в CL система типов - сильна

у них другие проблемы, когда лиспу в 1959-м нужен был GC - его просто взяли и написали, не жалуясь, что нет гигабайт ОЗУ для его работы

Угу. И они всегда есть.

я прекрасно обхожусь STL, и даже с Qt предпочитаю использовать std::vector, std::unordered_map etc.

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

.begin(), entry.second.end() и inserter забыл.

не забыл, выше писал про это, если пользоваться copy_if etc. - проще себе в отдельный хедер «шорткаты» дописать, чтоб код красивее был

^ less allocations

да, и в лямбде тоже, решил,что для примера не важно, хотя зря

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

проще себе в отдельный хедер «шорткаты» дописать, чтоб код красивее был

В std дописать или в другой namespace?

и в лямбде тоже

Я там const& добавил — будут auto, можно будет так же auto& писать, const он сам выведет.

quasimoto ★★★★
()

да и не говори, каждый раз как брался за c++ или bash всегда удивлялся какие не логичные.

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

взял вариант quasimoto за основу:

#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

template<class Source, class Destination, class Predicate>
void copy_if( const Source& s, Destination& d, Predicate pred ) {
    copy_if( s.begin(), s.end(), inserter( d, d.begin() ), pred );
}

using SubMap = map<string, vector<string>>;
template <typename T> using Map = map<T, SubMap>;

template <typename T>
static Map<T> compressDependencies(Map<T> const& dependencies) {
    Map<T> result;
    for (auto & entry : dependencies) {
        copy_if( entry.second, result[ entry.first ],
            [](const SubMap::value_type& subEntry) { return subEntry.second.size(); });
    }
    return result;
}

int main() {
    Map<int> m;
    m[0]["1"] = {};
    m[0]["2"] = { "0" };
    cout << m[0].size() << '\n';

    Map<int> r = compressDependencies( m );
    cout << r[0].size() << '\n';
}
~$ g++ -std=c++11 1.cpp
~$ ./a.out 
2
1
wota ★★
()
Последнее исправление: wota (всего исправлений: 2)
Ответ на: комментарий от wota

Ну если в Java написать классов вместо type aliases и какие-то свои утилиты для iterables сделать (типа как в guava или lambdaj — не разбираюсь), то в итоге может получиться не сильно хуже.

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

Так guava и lambdaj — это же библиотеки. Ну не входят в стандартную библиотеку, но почему бы их не использовать и в этом случае? Всё честно.

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

Нужны модули, концепты, репозитарии библиотек

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

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

Это всё задействуется только на этапе компиляции

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

Даже без всяких функциональных фишек на обычной жабе это выглядит вот так:

	private Map<Class<?>, Map<String, List<String>>> compressDependencies(
			Map<Class<?>, Map<String, List<String>>> dependencies ) {
		final Map<Class<?>, Map<String, List<String>>> result = new HashMap<>();
		for( Class<?> clazz : dependencies.keySet() ) {

			final Map<String, List<String>> desc = new HashMap<>();

			for( Entry<String, List<String>> d : dependencies.get( clazz ).entrySet() ) {
				List<String> value = d.getValue();
				if( value != null && !value.isEmpty() )
					desc.put( d.getKey(), value );
			}

			result.put( clazz, desc );
		}
		return result;
	}

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

Даже без всяких функциональных фишек на обычной жабе это выглядит вот так:

Ну вот и я говорю. Стоит хотя бы добавить небольшую разрядку по горизонтали — и совсем уже не говнокод.

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

У wota тоже обвёртка на пару строк (сама copy_if это несколько строк). Ну это проблемы Java, что аналогичного STL -> std не произошло, или не проблема — всё равно у всех куча своих com/org.*.

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

Это к тормозам приведет?

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

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

Это к тормозам приведет?

Какой вообще performance может быть с вот таким:

Map<Class<?>, Map<String, List<String>>>
?

Если реально нужен performance на Java, то и вот такое используют.

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

я надеюсь, ты в реальном коде так не пишешь ;)

В реальном коде у меня был бы нормальный итератор по мапе. И сложность доступа в hashmap - O(1).

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

O(1) - не значит мгновенно. Это, как минимум, один промах в кэше для на большом рабочем множестве. Кроме того, там довольно дорогая операция % используется внутри.

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

В реальном коде у меня был бы нормальный итератор по мапе.

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

И сложность доступа в hashmap - O(1).

во-первых от O(1) до O(n), как повезет, а во-вторых оценка сложности алгоритма не равна реальным затратам по времени, что бы ни было ключом - его надо прохешировать, а после выполнить полное сравнение, для строк, например, это не так уж и быстро

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

Вот на guava:

	private Map<Class<?>, Map<String, List<String>>> compressDependencies2(
			Map<Class<?>, Map<String, List<String>>> dependencies ) {
		return Maps.transformValues( dependencies, map -> Maps.filterValues( map, v -> !v.isEmpty() ) );
	}

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

компилябельный пример (оба):

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.google.common.collect.Maps.filterValues;
import static com.google.common.collect.Maps.transformValues;
import static java.util.Map.Entry;

public class Test {
	private Map<Class<?>, Map<String, List<String>>> compressDependencies(
			Map<Class<?>, Map<String, List<String>>> dependencies ) {

		final Map<Class<?>, Map<String, List<String>>> result = new HashMap<>();
		for( Entry<Class<?>, Map<String, List<String>>> clazz : dependencies.entrySet() ) {

			final Map<String, List<String>> desc = new HashMap<>();
			for( Entry<String, List<String>> d : clazz.getValue().entrySet() ) {
				List<String> value = d.getValue();
				if( !value.isEmpty() ) desc.put( d.getKey(), value );
			}
			result.put( clazz.getKey(), desc );
		}
		return result;
	}

	private Map<Class<?>, Map<String, List<String>>> compressDependencies2(
			Map<Class<?>, Map<String, List<String>>> dependencies ) {
		return transformValues( dependencies, map -> filterValues( map, v -> !v.isEmpty() ) );
	}
}


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

это вообще код (сходный) симптоматичный - то что там хранится в мапах исходя из терминов так хранится не должно. Это перл-стайл ООП на хешмапах.

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

Это всё понятно. Товарищ kamre выше статью на дельную статейку дал, о смысле жизни структур данных. Что и как они должны хранить.

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

И они еще борются за звание «Дома высокой культуры быта»(с)

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

P.S. самое смешное, когда на некоторых классах задач оказывается, что программа с GC работает быстрее, за счет более оптимального использования памяти и релокации данных.

код в студію!

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

У нас за последний год при наборе в отдел явы не было ни одного кандидата, который не знал бы scala(требования такого в вакансии не было) :)

молодых задорных модніков набіраете?

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

хотел бы посмотреть как бы вот такое, например, выглядело:

m[0]["2"] = { "0" };

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

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

Если реально нужен performance на Java, то и вот такое используют.

Последним шагом должно стать сжатие быстрым алгоритмом как записей по отдельности, так и сжатие между записями (как нормализация в БД). Тогда мы опустимся ниже планки 88MB. Скорость при этом может пострадать, но здесь это единственный способ набить память полезной инфой под завязку, не вываливаясь на диск.

А вообще, использование com.sun.Unsafe для последнего примера симптоматично. Там, где возникает потребность в такого рода оптимизациях, нужны компактные и/или сжатые структуры данных. Их реализация на Java будет очень неэффективна, так как они требуют прямого доступа к памяти, поинтерной арифметики и прочего кошмара программиста. Именно по этой причине я перебрался с Java на C++.

Если хочется максимально эффективно использовать память, но оставаться в Java, то это off-heap с компактными структурами данных, написанными на C++. GC скажет огромное человеческое спасибо.

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

" Ты понмиаешь что нельзя біло в 91 году зайти качнуть компилятор так же легко как сейчас, обен знаний был более медленным, " в 1991 году контора в которой трудился Гослинг говорила что «сеть это компьютер». так что с счем-счем а с возможностью чтото скачать или быть в курсе что делают соседи по индустрии у него было все отлично, btw Линус свое ядро когда в паблик выложил? уж не в 91ли?

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

Ты в 91 под какой стол ходил? Ты понмиаешь что нельзя біло в 91 году зайти качнуть компилятор так же легко как сейчас, обен знаний был более медленным

т.е. под «Не было никаких генериков в c++ когда с нее делали жаву.» ты понимал то, что Гослинг про них не слышал? окай

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

т.е. под «Не было никаких генериков в c++ когда с нее делали жаву.» ты понимал то, что Гослинг про них не слышал?

Нет. Мы дошли до того что в 91 году генерики только появились в с++ одновременно с жавой. А Гослинг не школота которая переписывает проект на каждый чих.

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

молодые задорные смелые Скалалазы высоко подняв голову смотрят вперёд.

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

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

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