Re[7]: Амбигус оператор
От: rg45 СССР  
Дата: 14.04.25 12:58
Оценка: 8 (1) +2
Здравствуйте, Marty, Вы писали:

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


_>>Оффтоп. Мимо проходил . По мотивам соседней темы посмотрел на твои is_bool/_is_char: https://github.com/al-martyn1/marty_format/blob/9bc7c73884f74e9fc8dbcc76e5612d504bc21cce/utils.h#L364C51-L364C52.

_>>Может не в курсе, но is_same суровый метод, и для него типы с cv-квалификаторами это разные типы, для игноар cv можно заюзать remove_cv_t, напр:
_>>
_>>template<typename T> using is_bool = std::is_same<std::remove_cv_t<T>, bool>;
_>>



M>Спасибо!


Здесь уместно будет заюзать std::decay дабы полностью очистить тип от разного рода модификаторов, в т.ч. и ссылок, и тем самым избавиться от лишнего геморроя при работе с формальными параметрами функций:

template<typename T> using is_bool = std::is_same<std::decay_t<T>, bool>;


А ещё все вот эти метафунции std::is_... канули в прошлое с приходом концептов. То же самое, но по-современному:

template<typename T> concept Bool = std::same_as<std::decay_t<T>, bool>;

static_assert(Bool<const bool&>);

void foo(Bool auto b) {/* . . . */}
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 14.04.2025 13:03 rg45 . Предыдущая версия . Еще …
Отредактировано 14.04.2025 13:02 rg45 . Предыдущая версия .
Re[3]: Амбигус оператор
От: rg45 СССР  
Дата: 15.04.25 14:01
Оценка: +1 :)
Здравствуйте, kov_serg, Вы писали:

_>Можно еще вот так извернуться если не нравиться разные но одинаковые типы

_>https://godbolt.org/z/4ocTWszE5

template<class T> struct Info {
    enum {
        size=sizeof(T),
        has_sign=(T)-1<0,
        is_2complement=(1&(T)-1),
        code=size*4+has_sign*2+is_2complement
     }; 
};

template<int n>void fnc(const void* t) {
    printf("fn<code=%d> size=%d sign=%d two_comliment=%d\n",n,n/4,(n>>1)&1,n&1); 
}
template<class T>void fn(const T &t) { fnc<Info<T>::code>(&t); }


У тебя пробелы платные, что ли?
--
Справедливость выше закона. А человечность выше справедливости.
Re[5]: Амбигус оператор
От: pilgrim_ Россия  
Дата: 14.04.25 12:31
Оценка: 12 (1)
Здравствуйте, Marty, Вы писали:

M>Написал пачечку единоообразных методов, там ручками перенаправляю в генерик метод: https://github.com/al-martyn1/marty_format/blob/9bc7c73884f74e9fc8dbcc76e5612d504bc21cce/marty_format.h#L1217


Оффтоп. Мимо проходил . По мотивам соседней темы посмотрел на твои is_bool/_is_char: https://github.com/al-martyn1/marty_format/blob/9bc7c73884f74e9fc8dbcc76e5612d504bc21cce/utils.h#L364C51-L364C52.
Может не в курсе, но is_same суровый метод, и для него типы с cv-квалификаторами это разные типы, для игноар cv можно заюзать remove_cv_t, напр:
template<typename T> using is_bool = std::is_same<std::remove_cv_t<T>, bool>;
Re[2]: Амбигус оператор
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 14.04.25 09:07
Оценка: +1
Здравствуйте, Chorkov, Вы писали:

C>Правильный список типов для перекрывания:

C>https://godbolt.org/z/YrhYcjKaY
C>
C>struct S {
C>    S& operator<<(char              ) { std::cout<<"char              "<<std::endl; return *this; }
C>    S& operator<<(signed char       ) { std::cout<<"signed char       "<<std::endl; return *this; }
C>    S& operator<<(unsigned char     ) { std::cout<<"unsigned char     "<<std::endl; return *this; }
C>    S& operator<<(signed short      ) { std::cout<<"signed short      "<<std::endl; return *this; }
C>    S& operator<<(signed int        ) { std::cout<<"signed int        "<<std::endl; return *this; }
C>    S& operator<<(signed long       ) { std::cout<<"signed long       "<<std::endl; return *this; }
C>    S& operator<<(signed long long  ) { std::cout<<"signed long long  "<<std::endl; return *this; }
C>    S& operator<<(unsigned short    ) { std::cout<<"unsigned short    "<<std::endl; return *this; }
C>    S& operator<<(unsigned int      ) { std::cout<<"unsigned int      "<<std::endl; return *this; }
C>    S& operator<<(unsigned long     ) { std::cout<<"unsigned long     "<<std::endl; return *this; }
C>    S& operator<<(unsigned long long) { std::cout<<"unsigned long long"<<std::endl; return *this; }
C>


C>Суть: типы short и int (char и short, int и long, long и long long) могут иметь одинаковый размер, оставаясь разными типами. Тяжкое наследие Си.

C>Типы с фиксированным размером (std::intXX_t), ссылаются на один из этих типов.
C>Можно представить, что компилятор будет поддерживать какой-то специальный __int64_t, и std::int64_t ссылается на него, но я такого не встречал.

Да, в итоге так и сделал
Маньяк Робокряк колесит по городу
Re[6]: Амбигус оператор
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 14.04.25 12:18
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Поломаться если и может, то только от кривых рук.


Ну вот я и решил без шаблонов сделать
Маньяк Робокряк колесит по городу
Амбигус оператор
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 11.04.25 10:05
Оценка:
Здравствуйте!

Переопределил operator<< для своего потока, для всех std::intN_t/uintN_t

При выводе unsigned long говорит, что оператор амбигус: "error C2593: 'operator <<' is ambiguous", и перечисляет все int* перегрузки, и ни одна ему не нравится больше других

Глянул, как они определены в MSVC
typedef signed char        int8_t;
typedef short              int16_t;
typedef int                int32_t;
typedef long long          int64_t;
typedef unsigned char      uint8_t;
typedef unsigned short     uint16_t;
typedef unsigned int       uint32_t;
typedef unsigned long long uint64_t;


Как видно, unsigned long тут нет. Можно было бы добавить перегрузку для unsigned long, но в другом компиляторе может быть всё по другому, и unsigned long уже будет в этом списке. Как тут быть?

Можно шаблон конечно сделать для целых типов, но пока хотелось бы решить без этого
Маньяк Робокряк колесит по городу
Re: Амбигус оператор
От: kov_serg Россия  
Дата: 11.04.25 13:33
Оценка:
Здравствуйте, Marty, Вы писали:

M>Можно шаблон конечно сделать для целых типов, но пока хотелось бы решить без этого


namespace ?
Re[2]: Амбигус оператор
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 11.04.25 13:51
Оценка:
Здравствуйте, kov_serg, Вы писали:

M>>Можно шаблон конечно сделать для целых типов, но пока хотелось бы решить без этого


_>namespace ?


Что неймспейс?

typedef — это просто алиас к существующему типу, перегрузки компилятор видит по оригинальному типа, пофик на алиас.

https://godbolt.org/z/qfnqoE9ao
Маньяк Робокряк колесит по городу
Re[3]: Амбигус оператор
От: kov_serg Россия  
Дата: 11.04.25 19:08
Оценка:
Здравствуйте, Marty, Вы писали:

M>>>Можно шаблон конечно сделать для целых типов, но пока хотелось бы решить без этого

_>>namespace ?
M>Что неймспейс?
https://godbolt.org/z/WGYabPK6r
то что ваш стрим не обязан быть в std

M>typedef — это просто алиас к существующему типу, перегрузки компилятор видит по оригинальному типа, пофик на алиас.

и что?
Re[4]: Амбигус оператор
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 11.04.25 19:16
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>>>namespace ?

M>>Что неймспейс?
_>https://godbolt.org/z/WGYabPK6r
_>то что ваш стрим не обязан быть в std

Не обязан, и не в std. И что? Я не очень понимаю мысль


M>>typedef — это просто алиас к существующему типу, перегрузки компилятор видит по оригинальному типа, пофик на алиас.

_>и что?

И то, что если сделать перегрузку для std::uint64_t, компилятор будет видеть её как перегрузку для unsigned long long
Маньяк Робокряк колесит по городу
Re[5]: Амбигус оператор
От: kov_serg Россия  
Дата: 11.04.25 19:39
Оценка:
Здравствуйте, Marty, Вы писали:

M>Не обязан, и не в std. И что? Я не очень понимаю мысль

Тогда уточните что вам надо

M>И то, что если сделать перегрузку для std::uint64_t, компилятор будет видеть её как перегрузку для unsigned long long

Так потому как это один и тот же тип.
Если надо сделать его как-то иначе выводить сделайте обёртку и явно указывайте что вам надо.
std::uint64_t v1; unsigned long long v2;
stream << OutputWrapper1(v1) << OutputWrapper2(v2);
или так https://godbolt.org/z/8Ga1E53cE
Re[6]: Амбигус оператор
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 11.04.25 19:45
Оценка:
Здравствуйте, kov_serg, Вы писали:

M>>Не обязан, и не в std. И что? Я не очень понимаю мысль

_>Тогда уточните что вам надо

Да вроде в стартовом посте написано вполне доходчиво

Я полагал, что перегрузок по std:(u)intXX_t хватит, чтобы покрыть все варианты интов, но оказалось, что нет. И на другом компиляторе тайпдефы могут быть другими, и если я под MSVC допилю недостающие, то с другим компилятором будет по-другому.


M>>И то, что если сделать перегрузку для std::uint64_t, компилятор будет видеть её как перегрузку для unsigned long long

_>Так потому как это один и тот же тип.

Так я вроде про это и говорил, а ты про какие-то namespace


_>Если надо сделать его как-то иначе выводить сделайте обёртку и явно указывайте что вам надо.

_>
_>std::uint64_t v1; unsigned long long v2;
_>stream << OutputWrapper1(v1) << OutputWrapper2(v2);
_>
или так https://godbolt.org/z/8Ga1E53cE


Маньяк Робокряк колесит по городу
Re[7]: Амбигус оператор
От: kov_serg Россия  
Дата: 11.04.25 19:47
Оценка:
Здравствуйте, Marty, Вы писали:

M>Да вроде в стартовом посте написано вполне доходчиво

нет

M>Я полагал, что перегрузок по std:(u)intXX_t хватит, чтобы покрыть все варианты интов, но оказалось, что нет. И на другом компиляторе тайпдефы могут быть другими, и если я под MSVC допилю недостающие, то с другим компилятором будет по-другому.

А нафига вы их все перегружаете?
Re[8]: Амбигус оператор
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 13.04.25 09:25
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>нафига вы их все перегружаете?


Ну вот мне тоже регулярно требуется разная реализация операций для 16-, 32- и 64-разрядных значений, ибо их вычислительная сложность заметно отличается. Пока операции используются непосредственно, и значения передаются типизированными переменными/константами, все хорошо. Как требуется выполнять операции над литералами, и/или обернуть их в шаблоны — начинается кошмар из-за integral promotions, запретить которые нет никакой возможности. И приходится костылить, на результат невозможно смотреть без отвращения.
Re: Амбигус оператор
От: Chorkov Россия  
Дата: 14.04.25 07:24
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!


M>Переопределил operator<< для своего потока, для всех std::intN_t/uintN_t


M>При выводе unsigned long говорит, что оператор амбигус: "error C2593: 'operator <<' is ambiguous", и перечисляет все int* перегрузки, и ни одна ему не нравится больше других


M>Глянул, как они определены в MSVC

M>
M>typedef signed char        int8_t;
M>typedef short              int16_t;
M>typedef int                int32_t;
M>typedef long long          int64_t;
M>typedef unsigned char      uint8_t;
M>typedef unsigned short     uint16_t;
M>typedef unsigned int       uint32_t;
M>typedef unsigned long long uint64_t;
M>


M>Как видно, unsigned long тут нет. Можно было бы добавить перегрузку для unsigned long, но в другом компиляторе может быть всё по другому, и unsigned long уже будет в этом списке. Как тут быть?


M>Можно шаблон конечно сделать для целых типов, но пока хотелось бы решить без этого


Правильный список типов для перекрывания:
https://godbolt.org/z/YrhYcjKaY
struct S {
    S& operator<<(char              ) { std::cout<<"char              "<<std::endl; return *this; }
    S& operator<<(signed char       ) { std::cout<<"signed char       "<<std::endl; return *this; }
    S& operator<<(unsigned char     ) { std::cout<<"unsigned char     "<<std::endl; return *this; }
    S& operator<<(signed short      ) { std::cout<<"signed short      "<<std::endl; return *this; }
    S& operator<<(signed int        ) { std::cout<<"signed int        "<<std::endl; return *this; }
    S& operator<<(signed long       ) { std::cout<<"signed long       "<<std::endl; return *this; }
    S& operator<<(signed long long  ) { std::cout<<"signed long long  "<<std::endl; return *this; }
    S& operator<<(unsigned short    ) { std::cout<<"unsigned short    "<<std::endl; return *this; }
    S& operator<<(unsigned int      ) { std::cout<<"unsigned int      "<<std::endl; return *this; }
    S& operator<<(unsigned long     ) { std::cout<<"unsigned long     "<<std::endl; return *this; }
    S& operator<<(unsigned long long) { std::cout<<"unsigned long long"<<std::endl; return *this; }


Суть: типы short и int (char и short, int и long, long и long long) могут иметь одинаковый размер, оставаясь разными типами. Тяжкое наследие Си.
Типы с фиксированным размером (std::intXX_t), ссылаются на один из этих типов.
Можно представить, что компилятор будет поддерживать какой-то специальный __int64_t, и std::int64_t ссылается на него, но я такого не встречал.
Отредактировано 14.04.2025 7:51 Chorkov . Предыдущая версия .
Re[2]: Амбигус оператор
От: kov_serg Россия  
Дата: 14.04.25 09:29
Оценка:
Здравствуйте, Chorkov, Вы писали:

C>Суть: типы short и int (char и short, int и long, long и long long) могут иметь одинаковый размер, оставаясь разными типами. Тяжкое наследие Си.

Можно еще вот так извернуться если не нравиться разные но одинаковые типы
https://godbolt.org/z/4ocTWszE5

C>Типы с фиксированным размером (std::intXX_t), ссылаются на один из этих типов.

C>Можно представить, что компилятор будет поддерживать какой-то специальный __int64_t, и std::int64_t ссылается на него, но я такого не встречал.
вот что харектерно, c++ всё есть для того чтобы иметь bigint но std::bigint нет.
Зато еще есть куча всяких целых спец типов __m128i __m256i __m512i
Re[3]: Амбигус оператор
От: rg45 СССР  
Дата: 14.04.25 11:24
Оценка:
Здравствуйте, Marty, Вы писали:

C>>Правильный список типов для перекрывания:

C>>https://godbolt.org/z/YrhYcjKaY
C>>
C>>struct S {
C>>    S& operator<<(char              ) { std::cout<<"char              "<<std::endl; return *this; }
C>>    S& operator<<(signed char       ) { std::cout<<"signed char       "<<std::endl; return *this; }
C>>    S& operator<<(unsigned char     ) { std::cout<<"unsigned char     "<<std::endl; return *this; }
C>>    S& operator<<(signed short      ) { std::cout<<"signed short      "<<std::endl; return *this; }
C>>    S& operator<<(signed int        ) { std::cout<<"signed int        "<<std::endl; return *this; }
C>>    S& operator<<(signed long       ) { std::cout<<"signed long       "<<std::endl; return *this; }
C>>    S& operator<<(signed long long  ) { std::cout<<"signed long long  "<<std::endl; return *this; }
C>>    S& operator<<(unsigned short    ) { std::cout<<"unsigned short    "<<std::endl; return *this; }
C>>    S& operator<<(unsigned int      ) { std::cout<<"unsigned int      "<<std::endl; return *this; }
C>>    S& operator<<(unsigned long     ) { std::cout<<"unsigned long     "<<std::endl; return *this; }
C>>    S& operator<<(unsigned long long) { std::cout<<"unsigned long long"<<std::endl; return *this; }
C>>


C>>Суть: типы short и int (char и short, int и long, long и long long) могут иметь одинаковый размер, оставаясь разными типами. Тяжкое наследие Си.

C>>Типы с фиксированным размером (std::intXX_t), ссылаются на один из этих типов.
C>>Можно представить, что компилятор будет поддерживать какой-то специальный __int64_t, и std::int64_t ссылается на него, но я такого не встречал.

M>Да, в итоге так и сделал


И это правильное решение. Ибо всё это разные типы, по которым всегда можно сделать перегрузку. В то время как типы intN_t/uintN_t — это алиасы с недетерминированным определением: https://timsong-cpp.github.io/cppwp/cstdint.syn#1.

В то же время я считаю, что ты напрасно отбрасываешь вариант с шаблонами. С шаблонами можно сделать все по-красоте. Обрати внимание на возможность перегрузок с приоритетами. Т.е. для каких-то групп типов можно предоставить общую перегрузку, а какие-то группы типов обработать более специальным образом:

https://coliru.stacked-crooked.com/a/150b460c99de60ae

#include <iostream>
#include <concepts>
#include <climits>

template <typename T>
concept Integer = std::integral<T>;

template <typename T>
concept SignedInteger = std::signed_integral<T>;

template <typename T>
concept UnsignedInteger = std::unsigned_integral<T>;

template <typename T, size_t size>
concept SignedIntegerOfSize = SignedInteger<T> and sizeof(T) * CHAR_BIT == size;

template <typename T, size_t size>
concept UnsignedIntegerOfSize = UnsignedInteger<T> and sizeof(T) * CHAR_BIT == size;

void foo(Integer auto value) {
   std::cout << "Integer: " << value << std::endl;
}

void foo(UnsignedInteger auto value) {
   std::cout << "Unsigned Integer: " << value << std::endl;
}

void foo(UnsignedIntegerOfSize<64> auto value) {
   std::cout << "Unsigned Integer(64): " << value << std::endl;
}

int main() {
   foo(42);     // Integer: 42
   foo(42U);    // Unsigned Integer: 42
   foo(42ULL);  // Unsigned Integer(64): 42
}
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 14.04.2025 11:36 rg45 . Предыдущая версия . Еще …
Отредактировано 14.04.2025 11:36 rg45 . Предыдущая версия .
Отредактировано 14.04.2025 11:31 rg45 . Предыдущая версия .
Отредактировано 14.04.2025 11:28 rg45 . Предыдущая версия .
Отредактировано 14.04.2025 11:27 rg45 . Предыдущая версия .
Re[4]: Амбигус оператор
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 14.04.25 11:36
Оценка:
Здравствуйте, rg45, Вы писали:


R>И это правильное решение. Ибо всё это разные типы, по которым всегда можно сделать перегрузку. В то время как типы intN_t/uintN_t — это алиасы с нерегламентированным определением: https://timsong-cpp.github.io/cppwp/cstdint.syn#1.


Да, я сначала не очень хорошо подумал, когда делал через std::u/intXX_t
Казалось красиво и единообразно, и по идее, должно было покрывать всё.

R>В то же время, я считаю, что ты напрасно отбрасываешь вариант с шаблонами. С шаблонами можно сделать все по красоте. Обрати внимание на возможность перегрузок с приоритетами. Т.е. для каких-то групп типов можно предоставить общую перегрузку, а какие-то группы типов обработать поотдельности:


Ну, у меня и другие типы, кроме интов используются, и, если говорить о других местах, то там и так шаблоны, не хотелось делать что у части шаблонов список шаблонных параметров другой. Плюс, мне надо чтобы работало ADL, с шаблонами может что-то сломаться (предполагается, что пользователь может использовать свои типы, и должен в своём NS определить для типа шаблонную функцию martyFormatValueFormat, где параметр шаблона тип строки, в которую надо конвертнуть значение пользовательского типа).

А по красоте с разными группами типов как раз особенно и не надо городить.

Написал пачечку единоообразных методов, там ручками перенаправляю в генерик метод: https://github.com/al-martyn1/marty_format/blob/9bc7c73884f74e9fc8dbcc76e5612d504bc21cce/marty_format.h#L1217
Маньяк Робокряк колесит по городу
Re[5]: Амбигус оператор
От: rg45 СССР  
Дата: 14.04.25 11:41
Оценка:
Здравствуйте, Marty, Вы писали:

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


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

M>Плюс, мне надо чтобы работало ADL, с шаблонами может что-то сломаться (предполагается, что пользователь может использовать свои типы, и должен в своём NS определить для типа шаблонную функцию martyFormatValueFormat, где параметр шаблона тип строки, в которую надо конвертнуть значение пользовательского типа).


Шаблоны сами по себе не ломают ADL. ADL — это про то, где и как компилятор будет искать кандидата для подстановки, а не про то, как кандидаты определены. ADL же отталикивается от типов фактических параметров. Поломаться если и может, то только от кривых рук.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 14.04.2025 11:50 rg45 . Предыдущая версия . Еще …
Отредактировано 14.04.2025 11:44 rg45 . Предыдущая версия .
Re[6]: Амбигус оператор
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 14.04.25 12:33
Оценка:
Здравствуйте, pilgrim_, Вы писали:

_>Оффтоп. Мимо проходил . По мотивам соседней темы посмотрел на твои is_bool/_is_char: https://github.com/al-martyn1/marty_format/blob/9bc7c73884f74e9fc8dbcc76e5612d504bc21cce/utils.h#L364C51-L364C52.

_>Может не в курсе, но is_same суровый метод, и для него типы с cv-квалификаторами это разные типы, для игноар cv можно заюзать remove_cv_t, напр:
_>
_>template<typename T> using is_bool = std::is_same<std::remove_cv_t<T>, bool>;
_>



Спасибо!
Маньяк Робокряк колесит по городу
Re[8]: Амбигус оператор
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 14.04.25 18:58
Оценка:
Здравствуйте, rg45, Вы писали:

R>А ещё все вот эти метафунции std::is_... канули в прошлое с приходом концептов. То же самое, но по-современному:


Не не, пока только C++17 по многим причинам (в тч и потому, что в тех же линупсах дефолтный компилер не самый свежий)

А SFINAE был уже в C++03, но я тогда не прочувствовал его в полной мере, сам тогда такого кода почти не писал, только использовал, часто не понимая, как оно работает, да и хелперов из C++11 — C++17 не было, сейчас хочу прочувствовать всё это полной ложкой

Я не на переднем крае (cutting edge), я в своё время долго писал на C++03, даже после выхода C++11, а) бесовщина какая-то, б) ждал пока станет буль менее мейнстримом в) да и вообще часто другими вещами занимался, сипипи был в фоне
Маньяк Робокряк колесит по городу
Re[9]: Амбигус оператор
От: rg45 СССР  
Дата: 14.04.25 20:28
Оценка:
Здравствуйте, Marty, Вы писали:

M>А SFINAE был уже в C++03, но я тогда не прочувствовал его в полной мере, сам тогда такого кода почти не писал, только использовал, часто не понимая, как оно работает, да и хелперов из C++11 — C++17 не было, сейчас хочу прочувствовать всё это полной ложкой


Ты просто возьми себе на заметку, что концепты имеют существенные преимущества перед SFINAE. Одним из главных преимуществ я бы назвал Partial ordering. При использовании SFINAE все перегрузки равноправны и необходимо обеспечить, чтоб все фильтры были взаимоисключающими во избежание конфликтов. При большом количестве перегрузок в таких областях как ввод-вывод, сериализация, форматирование и т.п. это иногда превращается в нехилый геморрой. Использование концептов же позволяет делать одни перегрузки более специальными, чем другие. Это очень похоже на то, как если бы мы писали перегрузки для базового и производного классов.
--
Справедливость выше закона. А человечность выше справедливости.
Re[10]: Амбигус оператор
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 14.04.25 20:41
Оценка:
Здравствуйте, rg45, Вы писали:

R>Ты просто возьми себе на заметку, что концепты имеют существенные преимущества перед SFINAE. Одним из главных преимуществ я бы назвал Partial ordering. При использовании SFINAE все перегрузки равноправны и необходимо обеспечить, чтоб все фильтры были взаимоисключающими во избежание конфликтов. При большом количестве перегрузок в таких областях как ввод-вывод, сериализация, форматирование и т.п. это иногда превращается в нехилый геморрой. Использование концептов же позволяет делать одни перегрузки более специальными, чем другие. Это очень похоже на то, как если бы мы писали перегрузки для базового и производного классов.


Да, спасибо, принял, буду иметь в виду. Но я пока на C++17, таки.

У меня есть проекты, которые должны, по моим представлениям, запускаться и на W2K, или хотя бы WinXP. А последняя MSVS — 2019, которая умеет в WinXP — умеет только в C++17

Ну и откушать SFINAE полной ложкой... Мои загоны...
Маньяк Робокряк колесит по городу
Re[3]: Амбигус оператор
От: _NN_  
Дата: 15.04.25 07:01
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>вот что харектерно, c++ всё есть для того чтобы иметь bigint но std::bigint нет.

_>Зато еще есть куча всяких целых спец типов __m128i __m256i __m512i
Когда решат как это сделать, тогда видимо и появится.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Амбигус оператор
От: kov_serg Россия  
Дата: 15.04.25 07:32
Оценка:
Здравствуйте, _NN_, Вы писали:

_>>вот что харектерно, c++ всё есть для того чтобы иметь bigint но std::bigint нет.

_>>Зато еще есть куча всяких целых спец типов __m128i __m256i __m512i
_NN>Когда решат как это сделать, тогда видимо и появится.
Давно надо было это сделать. Чего тянут не понятно.

а то с++ как правило делает так:
#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;

int main() {
   cpp_int u=1;
   for(unsigned i=2;i<=100;i++) u*=i;
   std::cout<<u<<std::endl;
   return 0;
}
  результат для 100!
In file included from example.cpp:2:
/usr/include/boost/multiprecision/cpp_int.hpp: In instantiation of ‘struct boost::multiprecision::backends::cpp_int_base<0, 4294967295, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, std::allocator<long long unsigned int>, false>’:
/usr/include/boost/multiprecision/cpp_int.hpp:1033:8:   required from ‘struct boost::multiprecision::backends::cpp_int_backend<>’
 1033 | struct cpp_int_backend
      |        ^~~~~~~~~~~~~~~
/usr/include/boost/multiprecision/number.hpp:1671:12:   required from ‘class boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<> >’
 1671 |    Backend m_backend;
      |            ^~~~~~~~~
example:6:12:   required from here
    6 |    cpp_int u=1;
      |            ^
/usr/include/boost/multiprecision/cpp_int.hpp:172:8: error: no class template named ‘rebind’ in ‘class std::allocator<long long unsigned int>’
  172 | struct cpp_int_base<MinBits, MaxBits, signed_magnitude, Checked, Allocator, false> : private Allocator::template rebind<limb_type>::other
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/multiprecision/cpp_int.hpp:174:66: error: no class template named ‘rebind’ in ‘class std::allocator<long long unsigned int>’
  174 |    typedef typename Allocator::template rebind<limb_type>::other allocator_type;
      |                                                                  ^~~~~~~~~~~~~~
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.