Информация об изменениях

Сообщение Re[8]: Философско-практические вопросы про метапрограммирова от 11.02.2023 11:11

Изменено 11.02.2023 11:47 rg45

Re[8]: Философско-практические вопросы про метапрограммирова
Здравствуйте, ботаныч, Вы писали:

М>>А можете, если есть время, более подробно написать

Б> почитав код ниже, мне хочется вопрос задать. Вам это в каком контексте надо? Если для продакшин кода, то специфика одна, если для библиотечного кода, да еще и header only подход будет сршенно разным, для нового продакшин кода, подход rg45 достаточно лаконичен, где стандарт и набор компиляторов практически предопределен и меняется довольно редко (хотя и там будут вопросы по скорости компиляции, иногда короткие лаконичные вещи компилируются дольше). Если же это библиотечный код, то часто предпочтение отдается дедовским версиям SFINAE громоздким, но покрывающим большее количество компиляторов. Также Вам может понадобиться столкнуться с периодом — до variadic templates.

М>>UPD

М>>Еще, наверно, можно попробовать оттолкнуться от std::is_same_v<T, std::set>
Б>
Б>namespace hl = std;
Б>template <template <typename... > class Tmp> struct holder {};

Б>template <typename T> struct extract : hl::false_type {};

Б>template <typename... Ts, template <typename... > class Tmpl>
Б>struct extract<Tmpl<Ts...>> : hl::true_type
Б>{
Б>    typedef holder<Tmpl> type;
Б>};
 
Б>int main()
Б>{
Б>  enum {v = std::is_same<typename extract<T>::type, holder<std::set>>::value};
Б>}
Б>


И как потом с этим подходом можно будет расширять правила для пользовательских типов, находящихся в клиенстких простраствах имен? Например, как нужно будет переписать вот этот фрагмент:

http://coliru.stacked-crooked.com/a/94e3814cbca1fdad

namespace lib_01 {

template <typename T>
using is_sorted_container = decltype(assume_sorted_range(std::declval<T>()));

} // namespace lib_01

namespace app_01 {
namespace app_02 {
namespace app_03 {

struct MySortedContainer
{

};
auto assume_sorted_range(const MySortedContainer&) -> std::true_type;

} // namespace app_03
} // namespace app_02
} // namespace app_01


И второй вопрос, что есть такого в моем коде, что может не скомпилироваться на "старом дедовском" компиляторе, который однако умеет SFINAE и вариадики? std::void_t что ли (C++17)? ну так он пишется в одну строчку своими силами. Что еще?

А просадка времени компиляции откуда возьмется (по сравнению с твоим вариантом)? Объявления функций все просадят что ли?
Re[8]: Философско-практические вопросы про метапрограммирова
Здравствуйте, ботаныч, Вы писали:

М>>А можете, если есть время, более подробно написать

Б> почитав код ниже, мне хочется вопрос задать. Вам это в каком контексте надо? Если для продакшин кода, то специфика одна, если для библиотечного кода, да еще и header only подход будет сршенно разным, для нового продакшин кода, подход rg45 достаточно лаконичен, где стандарт и набор компиляторов практически предопределен и меняется довольно редко (хотя и там будут вопросы по скорости компиляции, иногда короткие лаконичные вещи компилируются дольше). Если же это библиотечный код, то часто предпочтение отдается дедовским версиям SFINAE громоздким, но покрывающим большее количество компиляторов. Также Вам может понадобиться столкнуться с периодом — до variadic templates.

М>>UPD

М>>Еще, наверно, можно попробовать оттолкнуться от std::is_same_v<T, std::set>
Б>
Б>namespace hl = std;
Б>template <template <typename... > class Tmp> struct holder {};

Б>template <typename T> struct extract : hl::false_type {};

Б>template <typename... Ts, template <typename... > class Tmpl>
Б>struct extract<Tmpl<Ts...>> : hl::true_type
Б>{
Б>    typedef holder<Tmpl> type;
Б>};
 
Б>int main()
Б>{
Б>  enum {v = std::is_same<typename extract<T>::type, holder<std::set>>::value};
Б>}
Б>


И как потом с этим подходом можно будет расширять правила для пользовательских типов, находящихся в клиенстких простраствах имен? Например, как можно(нужно) переписать вот этот фрагмент:

http://coliru.stacked-crooked.com/a/94e3814cbca1fdad

namespace lib_01 {

template <typename T>
using is_sorted_container = decltype(assume_sorted_range(std::declval<T>()));

} // namespace lib_01

namespace app_01 {
namespace app_02 {
namespace app_03 {

struct MySortedContainer
{

};
auto assume_sorted_range(const MySortedContainer&) -> std::true_type;

} // namespace app_03
} // namespace app_02
} // namespace app_01


И второй вопрос, что есть такого в моем коде, что может не скомпилироваться на "старом дедовском" компиляторе, который однако умеет SFINAE и вариадики? std::void_t что ли (C++17)? ну так он пишется в одну строчку своими силами. Что еще?

А просадка времени компиляции откуда возьмется (по сравнению с твоим вариантом)? Объявления функций все просадят что ли?