Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 22.09.2017
Сообщений: 28

Как создать шаблон функции отдельно для знаковых и беззнаковых чисел

09.02.2018, 11:07. Показов 1391. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Имеется задача, создать шаблонную функцию для конвертации числа в строку. Но проблема в том, что при вызове функции sprintf и ей подобных надо в строке формата жёстко зашивать знаковость числа. Как указать в шаблоне, что он только для знаковой переменной (или бесзнаковой)?

Вот моя реализация шаблона:

C++
1
2
3
4
5
6
7
template <typename A>
CString ToString(A nValue)
{
    char acBuf[20];
    snprintf(acBuf, sizeof(acBuf), "%lu", long(nValue));
    return CString(acBuf);
}
Если шаблону передать знаковый тип, компилятор выдаёт предупреждение на функцию sprintf. Типа формат бесзнаковый, а аргумент знаковый.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.02.2018, 11:07
Ответы с готовыми решениями:

Сравнение знаковых и беззнаковых чисел
Возьмем пример: #include &lt;stdio.h&gt; int main() { if ( 1U &gt; -1 ) printf(&quot;1 &gt; -1&quot;); else printf(&quot;1 &lt;= -1\n&quot;);...

Из массива беззнаковых байтов в массив знаковых
Выручайте!!! Вопрос такой, как получить из массива беззнаковых байтов массив знаковых. Считываю информацию по COM порту, ко мне приходит...

Как создать отдельно список и массив из 20 случайных чисел
Как создать отдельно список и массив из случайных чисел для каждого, числа принимают случайное значение (функция random?)

13
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,244
09.02.2018, 12:21
А так разве нельзя
C++
1
snprintf(acBuf, sizeof(acBuf), "%lu", (unsigned long)nValue );
0
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
09.02.2018, 13:42
C++
1
2
3
4
5
6
7
8
9
10
#include <type_traits>
 
template <typename A>
CString ToString(A nValue)
{ 
    static_assert(!std::is_signed<A>::value, "Only unsigned types supported");
    char acBuf[20];
    snprintf(acBuf, sizeof(acBuf), "%lu", long(nValue));
    return CString(acBuf);
}
Добавлено через 13 секунд
http://en.cppreference.com/w/cpp/types/is_signed
0
0 / 0 / 0
Регистрация: 22.09.2017
Сообщений: 28
09.02.2018, 14:17  [ТС]
Цитата Сообщение от zss Посмотреть сообщение
А так разве нельзя
C++Выделить код
1
snprintf(acBuf, sizeof(acBuf), "%lu", (unsigned long)nValue );
При таком варианте ВСЕГДА будут отображаться бесзнаковые числа. И при передаче в функцию отрицательного числа будет выводиться бред. А мне нужно, чтобы один шаблон правильно работал и с знаковыми и бесзнаковыми числами.

Добавлено через 3 минуты
Цитата Сообщение от New man Посмотреть сообщение
1
C++
1
2
3
4
5
6
7
8
9
#include <type_traits>
template <typename A>
CString ToString(A nValue)
{ 
* * static_assert(!std::is_signed<A>::value, "Only unsigned types supported");
* * char acBuf[20];
* * snprintf(acBuf, sizeof(acBuf), "%lu", long(nValue));
* * return CString(acBuf);
}
Мне нужно, чтобы один шаблон правильно работал и с знаковыми и бесзнаковыми числами. Ваш вариант не подходит.
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
09.02.2018, 14:49
yanich89,
C++
1
static_assert(!std::is_signed<A>::value || std::is_signed<A>::value, "Only unsigned types supported");
Добавлено через 3 минуты
Цитата Сообщение от yanich89 Посмотреть сообщение
При таком варианте ВСЕГДА будут отображаться бесзнаковые числа. И при передаче в функцию отрицательного числа будет выводиться бред. А мне нужно, чтобы один шаблон правильно работал и с знаковыми и бесзнаковыми числами.
https://www.cyberforum.ru/cpp-... ment3.html
3.1 Уважительно относитесь к другим участникам форума.
0
Неэпический
 Аватар для Croessmah
18148 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,031
Записей в блоге: 1
09.02.2018, 15:07
C++
1
2
3
4
5
6
7
8
9
10
template <typename A>
CString ToString(A nValue)
{
    constexpr bool is_signed = std::numeric_limits<A>::is_signed;
    constexpr static char const * spec[2] = {"%lu", "%ld"};
    using value_t = typename std::conditional<is_signed, long, unsigned long>::type;
    char acBuf[std::numeric_limits<value_t>::digits10 + 2];
    snprintf(acBuf, sizeof(acBuf), spec[is_signed], static_cast<value_t>(nValue));
    return CString(acBuf);
}
пойдет?
0
0 / 0 / 0
Регистрация: 22.09.2017
Сообщений: 28
09.02.2018, 16:40  [ТС]
Цитата Сообщение от outoftime Посмотреть сообщение
3.1 Уважительно относитесь к другим участникам форума.
Я Вас понял, про уважение. Но не понял, в каком месте своих посланий я нарушил данное правило. Но всё равно извиняюсь.

Добавлено через 2 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
template <typename A>
CString ToString(A nValue)
{
* * constexpr bool is_signed = std::numeric_limits<A>::is_signed;
* * constexpr static char const * spec[2] = {"%lu", "%ld"};
* * using value_t = typename std::conditional<is_signed, long, unsigned long>::type;
* * char acBuf[std::numeric_limits<value_t>::digits10 + 2];
* * snprintf(acBuf, sizeof(acBuf), spec[is_signed], static_cast<value_t>(nValue));
* * return CString(acBuf);
}
пойдет?
К сожалению нет. Я не использую STL. Если Вы мне подскажите как реализовать данную функциональность самому, буду очень благодарен.
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
09.02.2018, 16:45
Цитата Сообщение от yanich89 Посмотреть сообщение
Я не использую STL
Может вам тогда лучше писать на Си?

Добавлено через 3 минуты
Цитата Сообщение от yanich89 Посмотреть сообщение
как реализовать данную функциональность самому
http://en.cppreference.com/w/cpp/types/is_signed Possible implementation
0
Неэпический
 Аватар для Croessmah
18148 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,031
Записей в блоге: 1
09.02.2018, 16:57
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
namespace details
{
    template<bool>
    struct is_signed_impl
    {
        enum {
            value = 1
        };
    };
 
 
    template<>
    struct is_signed_impl<false>
    {
        enum {
            value = 0
        };
    };
}
 
 
 
template<typename T>
struct is_signed
{
    enum {
        value = details::is_signed_impl<T(-1) < T(0)>::value
    };
};
 
template<bool Cond, typename T1, typename T2>
struct conditional
{
    typedef T1 type;
};
 
template<typename T1, typename T2>
struct conditional<false, T1, T2>
{
    typedef T2 type;
};
 
 
template <typename A>
CString ToString(A nValue)
{
    static bool const type_is_signed = is_signed<A>::value;
    static char const * const spec[2] = {"%lu", "%ld"};
    typedef typename conditional<type_is_signed, long, unsigned long>::type value_t;
    char acBuf[20];
    snprintf(acBuf, sizeof(acBuf), spec[type_is_signed], static_cast<value_t>(nValue));
    return CString(acBuf);
}
Заодно от C++11 избавился.
1
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
09.02.2018, 17:11
Цитата Сообщение от Croessmah Посмотреть сообщение
static bool const
Только вот разве, если вызвать функцию с знаковыми и беззнаковыми эту переменную можно будет менять? Она же static и const
0
0 / 0 / 0
Регистрация: 22.09.2017
Сообщений: 28
09.02.2018, 17:18  [ТС]
Цитата Сообщение от outoftime Посмотреть сообщение
Может вам тогда лучше писать на Си?
Если бы я писал на С, я бы не задавал вопросы про шаблоны. Просто мне не нужна лишняя библиотека в моём проекте. В контроллере, под который я пишу, крайне мало оперативки и памяти для хранения программы. По этому пока пишу без STL.
Цитата Сообщение от outoftime Посмотреть сообщение
http://en.cppreference.com/w/cpp/types/is_signed Possible implementation
Ходил по ссылке, смотрел. Рыл STL для Visual Studio, ничего не понял. Вот код, который меня интересует:
C++
1
2
3
4
5
6
7
8
template<class _Ty,
    bool = is_integral_v<_Ty>>
    struct _Sign_base
    {   // determine whether integral _Ty is a signed or unsigned type
    using _Uty = remove_cv_t<_Ty>;
    using _Signed = bool_constant<_Uty(-1) < _Uty(0)>;
    using _Unsigned = bool_constant<_Uty(0) < _Uty(-1)>;
    };
Что здесь означает
C++
1
using _Signed = bool_constant<_Uty(-1) < _Uty(0)>
?
0
Неэпический
 Аватар для Croessmah
18148 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,031
Записей в блоге: 1
09.02.2018, 17:24
Цитата Сообщение от outoftime Посмотреть сообщение
Только вот разве, если вызвать функцию с знаковыми и беззнаковыми эту переменную можно будет менять? Она же static и const
Разные типы - разные функции. У каждой будет своя константа is_signed, от которой, компилятор, скорее всего избавится. Но можно и руками от неё избавиться. Да и массив тоже не особо нужен.
1
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,360
Записей в блоге: 5
09.02.2018, 17:38
Цитата Сообщение от yanich89 Посмотреть сообщение
Что здесь означает
Тоже что и
Цитата Сообщение от Croessmah Посмотреть сообщение
details::is_signed_impl<T(-1) < T(0)>
Посмотрите его реализацию, это в точности то что вы хотели.
0
Неэпический
 Аватар для Croessmah
18148 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,031
Записей в блоге: 1
09.02.2018, 17:43
Еще можно так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
template<bool, typename T>
struct enable_if
{
   using type = T;
};
 
template<typename T>
struct enable_if<false, T>
{
};
 
 
template<typename T>
typename enable_if<(T(-1) < T(0)), CString>::type ToString(T nValue)
{
    char acBuf[20];
    snprintf(acBuf, sizeof(acBuf), "%ld", static_cast<long>(nValue));
    return CString(acBuf);
}
 
 
template<typename T>
typename enable_if<(T(-1) > T(0)), CString>::type ToString(T nValue)
{
    char acBuf[20];
    snprintf(acBuf, sizeof(acBuf), "%lu", static_cast<unsigned long>(nValue));
    return CString(acBuf);
}
Или даже вынести внутренности в две какие-нибудь ToStringImpl, а в шаблоне оставить только их вызов с преобразованием к нужному типу.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.02.2018, 17:43
Помогаю со студенческими работами здесь

Создать шаблон функции для построения очереди
Помогите, пожалуйста, сделать задачу: Реализовать шаблон функции для построения очереди и работы с ней(добавление, изменение,...

Как правильно создать шаблон функции
как мне правильно создать шаблон,чтобы работала ф-ция sub() ? #include&lt;iostream&gt; using namespace std; template&lt;typename...

Создать шаблон функции для подсчёта количества отрицательных элементов матриц
Создать шаблон функции для подсчёта количества отрицательных элементов матрицы A.Вызвать шаблон функции для матриц различного типа. ...

Заменить нулями числа, превосходящие заданное значение для массива 16-разрядных беззнаковых чисел
Заменить нулями числа, превосходящие заданное значение для массива 16-разрядных беззнаковых чисел. Как это реализовать?

Написать шаблон функции для сортировки массивов действительных и целых чисел
Заданы элементы массива. Написать шаблон функции для сортировки массивов действительных и целых чисел. Поможете?:scratch:


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru