Пример каноничного проекта?
От: cppguard  
Дата: 14.02.23 14:12
Оценка: -4
Я люблю запрыгивать в ветки о С++ и набрасывать, что оный не нужон. Но на самом деле я всегда внимательно изучаю любой инструмент, потому что люблю эффективную работу и экономию ресурсов. Так сложилось, что за всё время мне не попадался проект, который бы раскрыл С++ как уникальный язык. Адепты часто любят приводить пример с сортировкой, мол, только в С++ можно вставить функцию сравнения непосредственно в тело сортировки (умалчивая, правда, что от каждой такой вставки бинарник жиреет как боров), а в остальных языках приходится довольствоваться компараторами. Ну ещё про возможность отключения виртуальной таблицы я слышал, хотя в Java уже давно присутствует devirtualization. Ну и другие какие-то микрооптимизации под лозунгами "not pay for what you not use".

Теперь без шуток. Вы можете привести примеры проектов, которые действительно раскрывают способности С++1x? Не холивара ради, а для самообразования. Меня по большей части интересует defensive programming и метапрограммирование, потому что прирост производительности на 20% звучит круто, но в наше время нафиг никому не нужен, потому что пользователи спокойно терпят мобильные приложения под гигабайт, которые вечно тупят, и веб-страницы размером с дистибутив Windows 95. А вот возможность кратно уменьшить количество ошибок в проекте 1М LoC — дорогого стоит. Но и на любые другие проявления тоже будет интересно посмотреть.
Re: Инлайнинг функции сравнения
От: Qbit86 Кипр
Дата: 14.02.23 14:44
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Адепты часто любят приводить пример с сортировкой, мол, только в С++ можно вставить функцию сравнения непосредственно в тело сортировки (умалчивая, правда, что от каждой такой вставки бинарник жиреет как боров), а в остальных языках приходится довольствоваться компараторами.


Да нет, такое даже в .NET будет работать при определённых условиях. Правда, нужно брать достаточно новые версии API, где компаратаор передаётся не по старинке как интерфейс IComparer<T> (динамический run-time полиморфизм), а как параметр дженерика с констрейнтом TComparer where TComparer : IComparer<T> (статический полиморфизм, мономорфизация на этапе JIT-компиляции):
public static void Sort<T, TComparer>(this Span<T> span, TComparer comparer)
    where TComparer : IComparer<T>?
Глаза у меня добрые, но рубашка — смирительная!
Отредактировано 14.02.2023 14:45 Qbit86 . Предыдущая версия .
Re[2]: Инлайнинг функции сравнения
От: samius Япония http://sams-tricks.blogspot.com
Дата: 14.02.23 16:35
Оценка:
Здравствуйте, Qbit86, Вы писали:

Q>Да нет, такое даже в .NET будет работать при определённых условиях. Правда, нужно брать достаточно новые версии API

Где брать? Руками такое наколбасить на раз можно, хотелось бы увидеть достаточно новые версии именно API.
Re[3]: MemoryExtensions
От: Qbit86 Кипр
Дата: 14.02.23 16:50
Оценка: 14 (1)
Здравствуйте, samius, Вы писали:

S>Руками такое наколбасить на раз можно, хотелось бы увидеть достаточно новые версии именно API.


См., например, Sort() и BinarySearch() для Span'ов [1]

S>Где брать?


Я когда-то, когда увидел эти API, искал компараторы по исходникам BCL [2], что ещё есть похожего, и куда ещё такой подход внедряют.
Потому что такой подход для BCL всё же нетипичен, там издревле использовался OOP-Java-style вместо constrained generics для передачи компараторов и прочих стратегий/политик.
Но, емнип, там особенно ничего не было за пределами этих API для Span'ов.

[1] https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions?view=net-7.0
[2] https://github.com/dotnet/runtime
Глаза у меня добрые, но рубашка — смирительная!
Re: Пример каноничного проекта?
От: sergii.p  
Дата: 14.02.23 17:58
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Меня по большей части интересует defensive programming и метапрограммирование


вот лично по-моему мнению C++ может дать фору в безопасности любому языку с GC и общим наследником в виде Object.
Задавал недавно вопрос, как реализовать новый тип в .Net ветке.
Все решения мягко говоря многословны. И заставляет каждый тип реализовывать чуть ли не в отдельном файле.
В С++ это реализуется куда проще.
Общий класс:
template <typename T, typename>
struct NewType
{
    NewType(T v)
    : m_value{ std::move(v) }
    {}
    const T& value() const { return m_value; }
private:
    T m_value;
};
+ реализовать std::hash и компараторы


а дальше использование:
struct CityDim;
using City = NewType<std::string, CityDim>;

struct CountryDim;
using Country = NewType<std::string, CountryDim>;

struct CountryInfo{};

std::optional<CountryInfo> findCountry(const Country& c) {
    return std::nullopt;
}

int main()
{
    auto city = City{"Moskow"};
    auto country = Country{"Russia"};
    findCountry(city); // выдаст ошибку на этапе компиляции
}


Сразу можно вспомнить библиотеку boost::units. Аналоги есть конечно и на других языках, но они менее универсальны.

Ещё можно вспомнить такую либу как gsl и тип not_null. Такой реализовать на java/C# тяжело. Какое-то подобие ввели в виде оператора !! в C#. Но оно всё равно не то.

Конечно Rust в данном случае оставляем за скобками. Но то отдельная тема. Смотрим только на мейнстрим.
Re[2]: Пример каноничного проекта?
От: σ  
Дата: 14.02.23 19:57
Оценка:
SP>Конечно Rust в данном случае оставляем за скобками. Но то отдельная тема. Смотрим только на мейнстрим.
Тогда ты про Haskell и Swift забыл.
Re[2]: Пример каноничного проекта?
От: pilgrim_ Россия  
Дата: 14.02.23 21:07
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>Задавал недавно вопрос, как реализовать новый тип в .Net ветке.


Хм, и я тебе там дал пример...

SP>Все решения мягко говоря многословны. И заставляет каждый тип реализовывать чуть ли не в отдельном файле.

SP>В С++ это реализуется куда проще.

на почти точно такой же код на C#
https://dotnetfiddle.net/SfgzR6

  Скрытый текст
using System;

using City = NewType<string, CityDim>;
using Country = NewType<string, CountryDim>;

public struct CityDim {}
public struct  CountryDim {}
struct CountryInfo{};

public struct NewType<TIdentifier, TTag> : IComparable<NewType<TIdentifier, TTag>>, IEquatable<NewType<TIdentifier, TTag>>
    where TIdentifier : IComparable<TIdentifier>, IEquatable<TIdentifier>
{
    private TIdentifier _value;
    
    public NewType(TIdentifier value)
    {
        _value = value;
    }
    
    public TIdentifier Value
    {
        get { return _value; }
    }
    
    public override string ToString() 
    {
        return _value.ToString();
    }
        
    public override bool Equals(object obj)
    {
        if (obj is NewType<TIdentifier, TTag>)
        {
            var other = (NewType<TIdentifier, TTag>) obj;
            return Equals(other);
        }
        return false;
    }
        
    public override int GetHashCode()
    {
        return _value.GetHashCode();
    }
        
    public bool Equals(NewType<TIdentifier, TTag> other)
    {
        return _value.Equals(other.Value);
    }
        
    public int CompareTo(NewType<TIdentifier, TTag> other)
    {
        return _value.CompareTo(other.Value);
    }

    public static bool operator== (NewType<TIdentifier, TTag> id1, NewType<TIdentifier, TTag> id2)    
    {
        return id1.Equals(id2);
    }
        
    public static bool operator != (NewType<TIdentifier, TTag> id1, NewType<TIdentifier, TTag> id2)    
    {
        return !id1.Equals(id2);
    }
        
}

public class Program
{
    static CountryInfo? findCountry(Country c) {
        return null;
    }
    
    public static void Main()
    {
        var city = new City("Moskow");
        var country = new Country("Russia");

        findCountry(country); // ok
        //findCountry(city); // выдаст ошибку на этапе компиляции
        
        //Console.WriteLine("Are equals: {0}", city == country); // выдаст ошибку на этапе компиляции
        
        var city2 = new City("Moskow");
        Console.WriteLine("Are equals: {0}", city == city2);
    }
}
Re[2]: Пример каноничного проекта?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 15.02.23 09:05
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>В С++ это реализуется куда проще.

Фантазии

SP>Общий класс:

SP>
SP>template <typename T, typename>
SP>struct NewType
SP>{
SP>    NewType(T v)
SP>    : m_value{ std::move(v) }
SP>    {}
SP>    const T& value() const { return m_value; }
SP>private:
SP>    T m_value;
SP>};
SP>+ реализовать std::hash и компараторы
SP>


SP>а дальше использование:

SP>
SP>struct CityDim;
SP>using City = NewType<std::string, CityDim>;

SP>struct CountryDim;
SP>using Country = NewType<std::string, CountryDim>;

SP>struct CountryInfo{};

SP>std::optional<CountryInfo> findCountry(const Country& c) {
SP>    return std::nullopt;
SP>}

SP>int main()
SP>{
SP>    auto city = City{"Moskow"};
SP>    auto country = Country{"Russia"};
SP>    findCountry(city); // выдаст ошибку на этапе компиляции
SP>}
SP>


Как это делается на современном C#
CountryInfo? findCountry(in Country c) {
   return null;
}

struct CountryInfo{}
public record struct City(string Name);
public record struct Country (string Name);


Это весь код, он реализует структурную эквивалентность для каждого типа и не вызывает дополнительных аллокаций.
https://sharplab.io/#v2:EYLgtghglgdgPgYQPYFcYBcBOBPAkjAMyQH4ACA2AE2TS2wApZSaMdSBjASlIG8BYAFClhAAQDspGCgA20gNyCAvoMEBnLCnbpmqVnkJIeygSIDMpTAFN2STJVLrMm7QijoGIgIwAGSRDCWnAom5lY2dg4aWjq0bPRevjD+gcFAA


SP>Ещё можно вспомнить такую либу как gsl и тип not_null. Такой реализовать на java/C# тяжело. Какое-то подобие ввели в виде оператора !! в C#. Но оно всё равно не то.

Очень даже то. В коде выше ты не можешь передать null в конструктор City, хотя string это ссылочный тип.

SP>Конечно Rust в данном случае оставляем за скобками. Но то отдельная тема. Смотрим только на мейнстрим.

Раст примерно на уровне C#, только derive макрос надо написать
Re: Пример каноничного проекта?
От: scf  
Дата: 26.02.23 08:55
Оценка:
Здравствуйте, cppguard, Вы писали:

C>Теперь без шуток. Вы можете привести примеры проектов, которые действительно раскрывают способности С++1x? Не холивара ради, а для самообразования. Меня по большей части интересует defensive programming и метапрограммирование, потому что прирост производительности на 20% звучит круто, но в наше время нафиг никому не нужен.


Очевидный вывод — C++ не про стабильные приложения и не про метапрограммирование. Помимо игровых движков, есть любители (и профессионалы) писать серверные приложения на С++ — т.к. экономия цпу и памяти в плюсовых приложениях выливается в серьезную экономию трат на сервера.
Re[2]: Пример каноничного проекта?
От: CreatorCray  
Дата: 26.02.23 20:50
Оценка:
Здравствуйте, scf, Вы писали:

scf>Очевидный вывод — C++ не про стабильные приложения

С какого вдруг перепугу?
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Re: Пример каноничного проекта?
От: LuciferSaratov Россия  
Дата: 26.02.23 21:16
Оценка: +1
Здравствуйте, cppguard, Вы писали:

>потому что прирост производительности на 20% звучит круто, но в наше время нафиг никому не нужен,


Игроделам нужен, современные ААА-тайтлы это С++ (за редчайшими исключениями, с которыми тоже не все так однозначно).
Re[2]: Пример каноничного проекта?
От: cppguard  
Дата: 26.02.23 21:22
Оценка:
Здравствуйте, LuciferSaratov, Вы писали:

LS>Игроделам нужен, современные ААА-тайтлы это С++ (за редчайшими исключениями, с которыми тоже не все так однозначно).


С игроделами всё сложно, потому что они уже давно завязаны на консоли, которые до последнего времени можно было отнести к embedded platforms со всеми вытекающими.
Re: Пример каноничного проекта?
От: DiPaolo Россия  
Дата: 26.02.23 21:30
Оценка: +1
C>прирост производительности на 20% звучит круто, но в наше время нафиг никому не нужен
Спроси любого владельца бизнеса, хотел бы он уменьшение расходов на 20%?

C>А вот возможность кратно уменьшить количество ошибок в проекте 1М LoC — дорогого стоит


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

Ну и как выше уже писали: есть ряд областей, где не то, что 20%, где 5% уже будет успехом и конкурентным преимуществом.
Патриот здравого смысла
Re[3]: Пример каноничного проекта?
От: LuciferSaratov Россия  
Дата: 26.02.23 21:32
Оценка: +1
Здравствуйте, cppguard, Вы писали:

C>С игроделами всё сложно, потому что они уже давно завязаны на консоли, которые до последнего времени можно было отнести к embedded platforms со всеми вытекающими.


Консоли от embedded-подхода ушли очень давно, на всех консолях уже больше 15 лет как операционные системы.
Re[3]: Пример каноничного проекта?
От: CreatorCray  
Дата: 26.02.23 21:48
Оценка:
Здравствуйте, cppguard, Вы писали:

C>С игроделами всё сложно, потому что они уже давно завязаны на консоли, которые до последнего времени

Ещё в мою бытность геймдевелоперства консоли перестали быть embedded.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Re[4]: Пример каноничного проекта?
От: cppguard  
Дата: 27.02.23 02:03
Оценка:
Здравствуйте, LuciferSaratov, Вы писали:

LS>Консоли от embedded-подхода ушли очень давно, на всех консолях уже больше 15 лет как операционные системы.


Embedded это не отсутствие ОС, а работа с ограниченными ресурсами.
Re[2]: Пример каноничного проекта?
От: cppguard  
Дата: 27.02.23 02:06
Оценка:
Здравствуйте, DiPaolo, Вы писали:

C>>прирост производительности на 20% звучит круто, но в наше время нафиг никому не нужен

DP>Спроси любого владельца бизнеса, хотел бы он уменьшение расходов на 20%?

Это будет глупый вопрос. "Хотите снизить расходы на 20%"? — Да!, "а если для этого нужно нанять вместо команды java-среднячков С++-экспертов за офердофига"? — э...
Re[4]: Пример каноничного проекта?
От: cppguard  
Дата: 27.02.23 02:07
Оценка: :))
Здравствуйте, CreatorCray, Вы писали:

C>>С игроделами всё сложно, потому что они уже давно завязаны на консоли, которые до последнего времени

CC>Ещё в мою бытность геймдевелоперства консоли перестали быть embedded.

Напомни, в каком поколении приставок добавили возможность увеличивать RAM, менять CPU и GPU?
Re[5]: Пример каноничного проекта?
От: CreatorCray  
Дата: 27.02.23 02:08
Оценка: +1 -1
Здравствуйте, cppguard, Вы писали:

C>Напомни, в каком поколении приставок добавили возможность увеличивать RAM, менять CPU и GPU?


Вон у меня есть лапотоп, в котором это всё распаяно и поменять можно разишо только на заводе.
По твоему это embedded?
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Re[6]: Пример каноничного проекта?
От: cppguard  
Дата: 27.02.23 06:12
Оценка: :)
Здравствуйте, CreatorCray, Вы писали:

CC>Вон у меня есть лапотоп, в котором это всё распаяно и поменять можно разишо только на заводе.

CC>По твоему это embedded?

An embedded system is a computer system—a combination of a computer processor, computer memory, and input/output peripheral devices—that has a dedicated function within a larger mechanical or electronic system.


То есть, если некто криаторкрэй стал настольк оплатежеспособным, что под его ноут кто-то целенаправленно решил выпускать ПО, то таки да. Ну и компания здорового человека делает так, что ПО под целевую платформу не тормозит, не лагает и чувствует себя вполне нативненько. В этом и есть особенность embedded, по моему мнению. Этот же параметр делает Android, сюрприз-сюрприз!, НЕ embedded платформой, потому что ресурсы в общем случаи неизвестны, и современные разработчики тупо ориентируются на флагманы.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.