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

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

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

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

Б>я просто показал, что параметром шаблона неспециализированный шаблон низя, но сравнить можно — вот так, и ..там мало кода.


Нифига себе мало кода. Его мало, потому что ты не довел его до логического завершения. А ты доведи его хотя бы до определения метафункции и сравни:

  Мой вариант
// For standard containers, the traits must be defined beforehand
template <typename K, typename T, typename C, typename A>
auto assume_sorted_range(const std::map<K, T, C, A>&) -> std::true_type;

template <typename K, typename T, typename C, typename A>
auto assume_sorted_range(const std::multimap<K, T, C, A>&) -> std::true_type;

template <typename T, typename C, typename A>
auto assume_sorted_range(const std::set<T, C, A>&) -> std::true_type;

template <typename T, typename C, typename A>
auto assume_sorted_range(const std::multiset<T, C, A>&) -> std::true_type;

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

  Твой вариант
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;
};

template <typename, typename = void>
struct is_sorted_container : std::false_type {};

template <typename T>
struct is_sorted_container<T, std::enable_if_t<
    std::is_same<typename extract<T>::type, holder<std::set>>::value ||
    std::is_same<typename extract<T>::type, holder<std::map>>::value ||
    std::is_same<typename extract<T>::type, holder<std::multimap>>::value ||
    std::is_same<typename extract<T>::type, holder<std::multiset>>::value
>> : std::true_type {};


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

А еще поставь себя на место нового сотрудника, который недавно пришел и разбирается с исходниками компании. Какой вариант легче для понимания?
Re[12]: Философско-практические вопросы про метапрограммиров
Здравствуйте, ботаныч, Вы писали:

Б>я просто показал, что параметром шаблона неспециализированный шаблон низя, но сравнить можно — вот так, и ..там мало кода.


Нифига себе мало кода. Его мало, потому что ты не довел его до логического завершения. А ты доведи его хотя бы до определения метафункции и сравни:

  Мой вариант
// For standard containers, the traits must be defined beforehand
template <typename K, typename T, typename C, typename A>
auto assume_sorted_range(const std::map<K, T, C, A>&) -> std::true_type;

template <typename K, typename T, typename C, typename A>
auto assume_sorted_range(const std::multimap<K, T, C, A>&) -> std::true_type;

template <typename T, typename C, typename A>
auto assume_sorted_range(const std::set<T, C, A>&) -> std::true_type;

template <typename T, typename C, typename A>
auto assume_sorted_range(const std::multiset<T, C, A>&) -> std::true_type;

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

  Твой вариант
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;
};

template <typename, typename = void>
struct is_sorted_container : std::false_type {};

template <typename T>
struct is_sorted_container<T, std::enable_if_t<
    std::is_same<typename extract<T>::type, holder<std::set>>::value ||
    std::is_same<typename extract<T>::type, holder<std::map>>::value ||
    std::is_same<typename extract<T>::type, holder<std::multimap>>::value ||
    std::is_same<typename extract<T>::type, holder<std::multiset>>::value
>> : std::true_type {};


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

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