Constantine
что будет с результатом в ISO C++?
Constantine
вы там вообще учитывайте, что переполнение любого типа, кроме беззнакового это UB
Constantine
не implementation defined, а просто UB
Anatoly
https://godbolt.org/g/VXWxPX
Anatoly
да, точно
Alexander "SonnySlave"
пасиб
Anatoly
я не знаю что происходит в return /* ??? */ - static_cast<R>((-in) - static_cast<R>(1)) - static_cast<R>(1); но код генерит как вы и хотели
Constantine
очевидно диапазон [0x80*; 0x100*) отображается унарным минусом в диапазон [1; 0x80*], после чего вычитается 1, получается [0; 0x80*), это кастуется в знаковый тип, после чего 1 возвращается назад
Constantine
зачем писать static_assert если можно написать sfinae friendly условие
Anatoly
а зачем тут SFINAE? оно для того чтобы скрывать функции, а не чтобы делать ошибки "функция не найдена"
Constantine
потому что это условие, что функцию можно инстанцировать
Anatoly
вообще "not an error" намекает что фича придумана не для ошибок
Constantine
я не уверен, что стоит вникать в технические дискуссии
Constantine
поверьте, если вы начнете вместо макросов писать TMP код вы поймете, что лучше сразу написать так
Anatoly
так себе аргумент
Constantine
потому что над этой функцией можно как минимум поставить is_detected
Constantine
а не копипастить её условие на все подряд
Anatoly
что за is_detected ?
Constantine
http://en.cppreference.com/w/cpp/experimental/is_detected
Александр
Anatoly
ок, а зачем оно тут?
Constantine
namespace details {
template <typename T> using convert_result = decltype(convert(std::declval<T>())));
template <typename T> using can_use_convert = is_detected<convert_result, T>;
}
Constantine
и у вас есть SFINAE проверка что можно вызывать эту функцию на аргументе типа T
Anatoly
ок, есть проверка, а зачем?
Anatoly
и кстати функция должна называться не convert, а convert_unsigned_to_signed
Constantine
да пофиг
Александр
наличие static_assert тупо не даст даже проверить, возможно ли эту функцию вызвать. SFINAE-friendly вариант позволит проверить и сказать "незя"
Constantine
мне кажется я пытаюсь спорить с человеком, который не понимает, зачем нужен concept check
Anatoly
и кстати пользователям функции важнее видеть вменяемое сообщение об ошибке
Constantine
этот вопрос отправляется в комитет
Constantine
в действительности clang прогрессирует в этом направлении, он покажет ветку инстанцирования и где провал
Александр
Constantine
в действительности эта функция будет называться signed_cast и у нее в любом случае будет версия, пропускающая signed
Constantine
и еще какая-то версия для char, я не придумал
Anatoly
не, я понимаю что в сложном случае копипастить условие накладно. Но конкретно в случае этой функции - сойдет и static_assert
Constantine
зачем писать static_assert если можно ровно то же условие поставить на sfinae?
Constantine
ну разумеется кроме случаев, когда мы сейчас словим ODR violation
Constantine
и кроме случаев implementation_is_missing
Anatoly
если будет версия и для signed, то точно надо писать if constexpr (std::is_unsigned_v<T>) { ... } else {... }
Constantine
а если тип не signed и не unsigned
Constantine
например, char
Anatoly
что char? он либо signed либо unsigned
Constantine
батенька, да вы матчасть не знаете
Anatoly
видимо да (
Anatoly
а какой же он?
Constantine
https://godbolt.org/g/XqHRrb
Constantine
никакой
Constantine
а, хм
Constantine
все-таки is_signed
Constantine
я матчасть не знаю
Anatoly
нет, действительно "Plain char, signed char, and unsigned char are three distinct types"
Constantine
if T(-1) < T(0)
Constantine
там ключевая проверка
Anatoly
но в контексте is_signed / unsigned будет либо одно, либо другое
Constantine
сложный вопрос
Constantine
if T(-1) < T(0)
if T(0) < T(-1)
Constantine
остается третий случай T(-1) == T(0)
Aidar
Aidar
это анспецифиед
Aidar
вроде нассать на него
Aidar
прога то well-formed
Constantine
ну технически подразумевается, что платформа может представлять отрицательные числа знаковым битом
Constantine
без допкода
Aidar
можно чекать бит явно
Aidar
и если что двигать -1
Aidar
иначе не двигать -1
Constantine
двигать -1 плохо
Aidar
где это написано
Constantine
в шланговском кодовалидаторе)
Aidar
почему плохо, я не читал тот абзац стандарта но там он есть про сдвиг знаковых
Constantine
For negative a, the behavior of a « b is undefined.
Aidar
ок
Aidar
ну тогда надо сделать положительное сначала
Aidar
а потом сделать -число
Constantine
Constantine
я не видел в стандарте гарантий
Anatoly
ну если добавят новый тип, то придется переписать вашу функцию. делов-то