Re[9]: Cоздание базового шаблона минуя специализацию
От: so5team https://stiffstream.com
Дата: 27.10.22 09:19
Оценка:
Здравствуйте, Videoman, Вы писали:

S>>Конструктивная критика должна, как минимум, идти в https://stdcpp.ru/

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

Где я такое предлагал?

V>Ну посетовал немного, это запрещено на RSDN?


Вы назвали свое сетование конструктивной критикой.

На практике же лично я не понял ни что вас не устраивало (т.е. в чем именно у вас была проблема), ни как вы смогли решить свою проблему, ни как эта проблема решалась в вашей библиотеке (т.е. не увидел никаких реальных альтернатив подходу std::format/fmt::format).

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

S>>std::format взялся не на пустом месте. Много лет в OpenSource была fmtlib, автор которой потратил туеву хучу времени и сил на то, чтобы выложить это в OpenSource, снабдить документацией, среагировать на огромное количество issues, принять кучу pull-request-ов, выслушать в свой адрес всякое-разное. А потом еще и принять участие в формировании предложения в стандарт, и пройти вместе с другими соавторами через процесс включения в стандарт.

V>Знаем знаем как всё там не на пустом месте. Ребята из Microsoft запилили библиотеку для своих личных нужд и пропихнули её в стандарт, т.к. могли.

Мы все еще говорим про fmtlib и std::format?

V>Но зачем так яростно его защищать, даже если там есть очевидные недостатки


Можно хотя бы одну цитату из моих слов, из которой бы следовало, что я защищаю std::format (или какое-либо из технических решений, примененных в std::format)?
Re[7]: Cоздание базового шаблона минуя специализацию
От: so5team https://stiffstream.com
Дата: 27.10.22 09:32
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Для остальных классов можно хотя бы дать возможность не подключать заголовки стандартных форматеров, а использовать свои.


Простите, а это как?

Вот, допустим, есть специализация std::formatter<std::time_t>. Вы не подключаете заголовок, в котором эта специализация определена, а делаете собственную специализацию std::formatter<std::time_t> в своем .cpp-файле, но в пространстве имен std.

Я правильно вас понял?
Re[8]: Cоздание базового шаблона минуя специализацию
От: Videoman Россия https://hts.tv/
Дата: 27.10.22 11:35
Оценка:
Здравствуйте, so5team, Вы писали:

S>Вот, допустим, есть специализация std::formatter<std::time_t>. Вы не подключаете заголовок, в котором эта специализация определена, а делаете собственную специализацию std::formatter<std::time_t> в своем .cpp-файле, но в пространстве имен std.


S>Я правильно вас понял?


Нет. Если ввести какой-нибудь формальный шаблонный параметр, который будет контролировать область поиска, то в случае реализация форматеров на функциях, ADL не увидит их и начнет искать в заданном вами найспейсе.
Re[9]: Cоздание базового шаблона минуя специализацию
От: so5team https://stiffstream.com
Дата: 27.10.22 11:39
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Нет. Если ввести какой-нибудь формальный шаблонный параметр, который будет контролировать область поиска, то в случае реализация форматеров на функциях, ADL не увидит их и начнет искать в заданном вами найспейсе.


Очень не хватает примеров. Мне до сих пор не понятно, что значит "реализация форматеров на функциях".
Re[10]: Cоздание базового шаблона минуя специализацию
От: Videoman Россия https://hts.tv/
Дата: 27.10.22 11:55
Оценка:
Здравствуйте, so5team, Вы писали:

S>Очень не хватает примеров. Мне до сих пор не понятно, что значит "реализация форматеров на функциях".


Посмотрите доклад Полухина
  C++ трюки из Такси
C++ трюки из Такси

У него там хорошо объясняется подход.
Re[11]: Cоздание базового шаблона минуя специализацию
От: so5team https://stiffstream.com
Дата: 27.10.22 12:00
Оценка:
Здравствуйте, Videoman, Вы писали:

S>>Очень не хватает примеров. Мне до сих пор не понятно, что значит "реализация форматеров на функциях".


V>Посмотрите доклад Полухина


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

Ну OK, пересмотрю доклад и буду гадать, а как Videoman это все сам понял.

Конструктивно, однако.
Re[12]: Cоздание базового шаблона минуя специализацию
От: Videoman Россия https://hts.tv/
Дата: 27.10.22 12:36
Оценка:
Здравствуйте, so5team, Вы писали:

S>И библиотека у вас секретная, даже фрагмента оттуда увидеть нельзя.

S>И вы настолько заняты, что минимальный пример продемонстрировать не можете.

S>Ну OK, пересмотрю доклад и буду гадать, а как Videoman это все сам понял.


S>Конструктивно, однако.


Ну чо вы такой душный, а?! Ну никакого позитива. Отдельной библиотеки нет, есть огромная библиотека-платформа для всего. Работает под Linux и Windows. Отодрать от туда именно форматирование, не могу, т.к. писалось оно еще с 2008-года, т.к. тогда нужна была поддержка не только std строк, но и MFC/ATL — строк и т.д. Код там не для показа, честно. Я по мере сил выкидываю от туда всё, что появляется в новых стандартах С++, изолирую законченные части и выкладываю в опен сорс, например:
slimcpplib — вот
sutfcpplib — и вот

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

Где угодно пишем:
archive_t arch = pack(custom_class{}, as<archive_t>);

ADL ищет pack сначала в текущем пространстве имен, потом с пространстве имен custom_class, а если не найдет то в пространстве имен archive_t — моем стандартном. Эти три пространсва имен могут быть разными. Отсюда и гибкость.
Отредактировано 27.10.2022 12:40 Videoman . Предыдущая версия . Еще …
Отредактировано 27.10.2022 12:38 Videoman . Предыдущая версия .
Re[13]: Cоздание базового шаблона минуя специализацию
От: so5team https://stiffstream.com
Дата: 27.10.22 13:29
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Ну чо вы такой душный, а?!


А я вообще старый и мерзкий старикашка.

V>В двух словах:


V>
V>archive_t arch = pack(custom_class{}, as<archive_t>);
V>


Как это перенести на вот такой способ записи:
int a = ...;
std::time_t b = ...;
print(std::cout, "Value {} at {}", a, b);

если я хочу time_t форматировать не так, как это делает некий задействованный мной print (пусть он будет стандартным)?

Здесь же есть только форматная строка (которая парсится не мной) и ссылки на значения, типы которых могут вообще не иметь отношения к моей библиотеке. Что-то мне не видно где здесь вообще форматеры для print-а указать можно.
Re[14]: Cоздание базового шаблона минуя специализацию
От: Videoman Россия https://hts.tv/
Дата: 27.10.22 14:22
Оценка: 8 (1)
Здравствуйте, so5team, Вы писали:

S>Как это перенести на вот такой способ записи:

S>
S>int a = ...;
S>std::time_t b = ...;
S>print(std::cout, "Value {} at {}", a, b);
S>

S>если я хочу time_t форматировать не так, как это делает некий задействованный мной print (пусть он будет стандартным)?

S>Здесь же есть только форматная строка (которая парсится не мной) и ссылки на значения, типы которых могут вообще не иметь отношения к моей библиотеке. Что-то мне не видно где здесь вообще форматеры для print-а указать можно.


Могу рассуждать только гипотетически. Допустим мы можем добавить более низкоуровневую функцию print_as:

namespace my_namespace
{
struct my_trait{};
}

namespace std
{
std::print_as(std::cout, std::format_as<my_namespace::my_trait>(), "Value {} at {}", a, b);
}
Где-то в потрохах мы делегируем std::format_as<my_trait>() до каждого форматера, который является функцией и получает его в качестве аргумента. Тогда если отключены стандартные форматеры, ADL будет искать во всех остальных местах, в том числе в my_namespace. А std::print для удобства пусть вызывает что-то типа: std::print_as(std::cout, std::format_as<std::format_traits>, "Value {} at {}", a, b);
Re[10]: Cоздание базового шаблона минуя специализацию
От: Videoman Россия https://hts.tv/
Дата: 27.10.22 14:32
Оценка:
Здравствуйте, so5team, Вы писали:

S>Мы все еще говорим про fmtlib и std::format?


S>Можно хотя бы одну цитату из моих слов, из которой бы следовало, что я защищаю std::format (или какое-либо из технических решений, примененных в std::format)?


Выглядит что защищаете, потому-что не хотите признать что некоторые вещи нельзя сделать, а некоторые непонятно как делать в теперь уже отлитой в камне парадигме. И
  вот чувак из Microsoft
url=https://www.youtube.com/watch?v=zssTF1uhxtM&amp;list=LL&amp;index=6&amp;ab_channel=CppCon]Why does std::format do that? — Charlie Barto — CppCon 2021[/url]

прямо докладывает, что особо сильно не думали, увидели хорошую, я не спорю, библиотеку, она им понравилась и они её прямо почти один в один перенесли в стандарт. Предложение было от Microsoft и они же её первыми заимплементили для VC.
Re[15]: Cоздание базового шаблона минуя специализацию
От: so5team https://stiffstream.com
Дата: 27.10.22 15:45
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Где-то в потрохах мы делегируем std::format_as<my_trait>() до каждого форматера, который является функцией и получает его в качестве аргумента. Тогда если отключены стандартные форматеры, ADL будет искать во всех остальных местах, в том числе в my_namespace. А std::print для удобства пусть вызывает что-то типа: std::print_as(std::cout, std::format_as<std::format_traits>, "Value {} at {}", a, b);


И что мешает внести такое предложение? Хотя бы вот сюда: https://stdcpp.ru/proposals/
Если людей это заинтересует, то они доведут это до формального предложения комитету.

Меня в таком подходе, например, сильно смущает такой момент: допустим, мы линкуем два объектника. В одном используются вызовы std::print (которые трансформируются в std::print_as(..., std::format_as<std::format_traits>, ...)), а в другом вызовы std::print_as(.., std::format_as<my_traits>, ...). Поскольку std::print_as шаблонная, то компилятор сгенерирует и std::print_as для std::format_traits, и для my_traits. Т.е. мы получим две копии практически одного и того же кода. На ровном месте, по сути.
Re[11]: Cоздание базового шаблона минуя специализацию
От: so5team https://stiffstream.com
Дата: 27.10.22 15:50
Оценка:
Здравствуйте, Videoman, Вы писали:

S>>Мы все еще говорим про fmtlib и std::format?


S>>Можно хотя бы одну цитату из моих слов, из которой бы следовало, что я защищаю std::format (или какое-либо из технических решений, примененных в std::format)?


V>Выглядит что защищаете


Т.е. цитат нет, но выглядит?

V>потому-что не хотите признать что некоторые вещи нельзя сделать, а некоторые непонятно как делать в теперь уже отлитой в камне парадигме.


Откуда следует что я что-то признаю или не признаю? С цитатами, плз.

V>прямо докладывает, что особо сильно не думали, увидели хорошую, я не спорю, библиотеку, она им понравилась и они её прямо почти один в один перенесли в стандарт. Предложение было от Microsoft и они же её первыми заимплементили для VC.


Т.е. роль Microsoft-а лишь в том, что они взяли на себя труд провести fmtlib через процедуру стандартизации. Но про это обязательно нужно высказаться вот в таком духе:

> Ребята из Microsoft запилили библиотеку для своих личных нужд и пропихнули её в стандарт, т.к. могли.


Добавить сюда еще и:

> А я говорил, что люди принимающие стандарты, по ходу вообще не думают, последнее время.


и чуть ли не картина маслом вырисовывается.
Re[16]: Cоздание базового шаблона минуя специализацию
От: Videoman Россия https://hts.tv/
Дата: 27.10.22 16:44
Оценка:
Здравствуйте, so5team, Вы писали:

S>И что мешает внести такое предложение? Хотя бы вот сюда: https://stdcpp.ru/proposals/

S>Если людей это заинтересует, то они доведут это до формального предложения комитету.

Теоретически ничего не мешает. Практически, я только неделю как погрузился в std::format и пока изучаю исходники и занят своей работой. Что бы оформить предложение, нужно время. Время появиться, обязательно сделаю, тем более если вы считаете, что это имеет смысл и что это вообще кто-то читает.

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

S>Меня в таком подходе, например, сильно смущает такой момент: допустим, мы линкуем два объектника. В одном используются вызовы std::print (которые трансформируются в std::print_as(..., std::format_as<std::format_traits>, ...)), а в другом вызовы std::print_as(.., std::format_as<my_traits>, ...). Поскольку std::print_as шаблонная, то компилятор сгенерирует и std::print_as для std::format_traits, и для my_traits. Т.е. мы получим две копии практически одного и того же кода. На ровном месте, по сути.


Ну это стандартные издержки шаблонов, можно с легкостью нагенерировать кучу машинного кода. Зато быстро ! Нужно будет подумать как это оптимизировать. Например, поскольку аргумент формальный, его можно передавать как параметр шаблона и только в конце инстанцировать при передаче в сам formatter. Такое компилятору будет проще оптимизировать?
Re[17]: Cоздание базового шаблона минуя специализацию
От: so5team https://stiffstream.com
Дата: 27.10.22 17:01
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Подход с функциями хорош еще и тем, что работают стандартные преобразования.


Я вот хоть убей не вижу где же здесь функции.
Re: Cоздание базового шаблона минуя специализацию
От: Sm0ke Россия ksi
Дата: 27.10.22 20:30
Оценка:
Здравствуйте, Videoman, Вы писали:

Заведите второй параметр шаблона с именем traits_t. Заведите разные траитсы. И при специализации для int указывай нужный траит.

template <typename type_t, template <typename> typename traits_t>
struct object {
    using t_traits = traits_t<type_t>;
    void print() { t_traits::print(this); }
};

template <typename type_t>
struct trait1 {
    static void print(type_t * p) { std::cout << "trait 1"; }
};

template <typename type_t>
struct trait2 {
    static void print(type_t * p) { std::cout << "trait 2"; }
};

int main() {
    object<int, trait1> obj;
    obj.print();
    return 0;
}
Re[2]: Cоздание базового шаблона минуя специализацию
От: rg45 СССР  
Дата: 28.10.22 06:51
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Заведите второй параметр шаблона с именем traits_t.


Боюсь, это не тот случай, когда это осуществимо. Стартовое сообщение хоть и сформулировано для общего случая, но по дальнейшему обсуждению ясно, что речь идет об std::formatter, primary template которого объявлен в стандартной библиотеке.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[18]: Cоздание базового шаблона минуя специализацию
От: rg45 СССР  
Дата: 28.10.22 07:13
Оценка: +1
Здравствуйте, so5team, Вы писали:

S>Я вот хоть убей не вижу где же здесь функции.


Так о том и речь, что их нет, а вместо функций — шаблон класса std::formatter. А если бы std::format для кастомизации использовал бы не шаблон класса со специализациями, а неквалифицированный вызов функции с каким-то предопределенным именем, это могло бы дать ряд преимуществ:


Если что-то и упустил, по-моему, этого списка уже достаточно.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[19]: Cоздание базового шаблона минуя специализацию
От: so5team https://stiffstream.com
Дата: 28.10.22 07:15
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, so5team, Вы писали:


S>>Я вот хоть убей не вижу где же здесь функции.


R>Так о том и речь, что их нет, а вместо функций — шаблон класса std::formatter. А если бы std::format для кастомизации использовал бы не шаблон класса со специализациями, а неквалифицированный вызов функции с каким-то предопределенным именем, это могло бы дать ряд преимуществ:


Вынужден повторить то, что уже писал: очень не хватает примеров. У вас одна картина в голове, у Videoman вторая, у меня третья. Все это можно было бы привести к общему знаменателю несколькими примерами, но вот примеров-то никто и не приводит
Re[20]: Cоздание базового шаблона минуя специализацию
От: rg45 СССР  
Дата: 28.10.22 07:29
Оценка:
Здравствуйте, so5team, Вы писали:

S>Вынужден повторить то, что уже писал: очень не хватает примеров. У вас одна картина в голове, у Videoman вторая, у меня третья. Все это можно было бы привести к общему знаменателю несколькими примерами, но вот примеров-то никто и не приводит


Ну, я изложил свой взгляд на предмет и надеялся, что словесного описания будет достаточно. На примеры сейчас времени не хватает, сорри.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[19]: Cоздание базового шаблона минуя специализацию
От: so5team https://stiffstream.com
Дата: 28.10.22 07:41
Оценка:
Здравствуйте, rg45, Вы писали:

R>Как частный случай — форматтер, определенный для базового класса автоматом будет работать и для всех производных, для которых не предоставлена своя собственая версия форматтера;


Это вроде как и сейчас в fmtlib возможно (полагаю, что и в std::format). Пример прямо из документации к fmtlib:
#include <type_traits>
#include <fmt/format.h>

struct A {
  virtual ~A() {}
  virtual std::string name() const { return "A"; }
};

struct B : A {
  virtual std::string name() const { return "B"; }
};

template <typename T>
struct fmt::formatter<T, std::enable_if_t<std::is_base_of<A, T>::value, char>> :
    fmt::formatter<std::string> {
  template <typename FormatCtx>
  auto format(const A& a, FormatCtx& ctx) const {
    return fmt::formatter<std::string>::format(a.name(), ctx);
  }
};

int main() {
  B b;
  A& a = b;
  fmt::print("{}", a); // prints "B"
}


https://godbolt.org/z/1G1bhhfso
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.