Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Croessmah
Эксперт CЭксперт С++
13209 / 7480 / 841
Регистрация: 27.09.2012
Сообщений: 18,389
Записей в блоге: 3
Завершенные тесты: 1
#1

Обертка над boost::lexical_cast для работы с unsigned типами - C++

31.01.2016, 15:29. Просмотров 1047. Ответов 23

Пару дней назад выяснилось, что boost::lexical_cast
не удовлетворяет нескольким требованиям в моей программе.
boost::lexical_cast отказывается обрабатывать и выбрасывает исключение,
если имеются пробелы в начале или в конце входной строки.
Также для unsigned типов, отрицательные значения обрабатываются нормально, т.е., например,
boost::lexical_cast<unsigned int>("-1") даст вполне валидное значение.
Для моих целей эти два факта были неприемлемы.
Собственно, Ticket #5494 как раз об этом,
и там был представлен такой велосипед:
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
#include <boost/lexical_cast.hpp>
#include <boost/type_traits/is_unsigned.hpp>
 
template <bool is_unsigned>
struct unsigned_checker
{
    template<typename String_type>
    static inline void do_check(const String_type & str) { }
};
 
template <>
struct unsigned_checker<true>
{
    template<typename String_type>
    static inline void do_check(const String_type & str)
    {
        if( str[0] == '-' ) boost::throw_exception( boost::bad_lexical_cast() );
    }
};
 
template<typename Target, typename Source>
inline Target forced_lexical_cast(const Source &arg)
{
    unsigned_checker< boost::is_unsigned<Target>::value >::do_check(arg);
    return boost::lexical_cast<Target>( arg );
}
Но для моих целей он также не подходит, т.к. кидает исключение и для строки "-0",
а ведь "-0", как и "+0" - вполне валидные значения.
Поэтому был написан велосипед:
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
namespace detail
{
    struct string_cast_impl
    {
        template<typename TargetType>
        static
        std::enable_if_t<std::is_unsigned<TargetType>::value, TargetType>
        cast(const std::string& source)
        {
            if (!source.empty() && source[0] == '-'){
                TargetType result = boost::lexical_cast<TargetType>(source) ;
                return (result!=0) ? throw boost::bad_lexical_cast(),TargetType(0) : result  ;
            }
            return boost::lexical_cast<TargetType>(source);
        }
 
 
 
        template<typename TargetType>
        static
        std::enable_if_t<!std::is_unsigned<TargetType>::value, TargetType>
        cast(const std::string& source)
        {
            return boost::lexical_cast<TargetType>(source) ;
        }
    };
}//end of detail
 
 
 
template<typename TargetType, typename StringType>
std::decay_t<TargetType> string_cast(StringType&& source)
{
    using DecayType = std::decay_t<TargetType> ;
    std::string str(std::forward<StringType>(source)) ;
    boost::trim(str) ;
    return detail::string_cast_impl::cast<DecayType>(str) ;
}
Решил выложить, вдруг кому пригодится, или будут дополнения/исправления.

Использование:
C++
1
2
3
4
5
int main(int argc, char ** argv)
{
    std::cout << string_cast<int>("-100") << std::endl ;
    std::cout << string_cast<unsigned int>("-100") << std::endl ;
}

P.S. Спасибо пользователям Kastaneda и hoggy за правки и дополнения.

Добавлено через 31 минуту
Вариант под C++11:
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
namespace detail
{
    struct string_cast_impl
    {
        template<typename TargetType>
        static
        typename std::enable_if<std::is_unsigned<TargetType>::value, TargetType>::type
        cast(const std::string& source)
        {
            if (!source.empty() && source[0] == '-'){
                TargetType result = boost::lexical_cast<TargetType>(source) ;
                return (result!=0) ? throw boost::bad_lexical_cast(),TargetType(0) : result  ;
            }
            return boost::lexical_cast<TargetType>(source);
        }
 
 
 
        template<typename TargetType>
        static
        typename std::enable_if<!std::is_unsigned<TargetType>::value, TargetType>::type
        cast(const std::string& source)
        {
            return boost::lexical_cast<TargetType>(source) ;
        }
    };
}//end of detail
 
 
 
template<typename TargetType, typename StringType>
typename std::decay<TargetType>::type string_cast(StringType&& source)
{
    using DecayType = typename std::decay<TargetType>::type ;
    std::string str(std::forward<StringType>(source)) ;
    boost::trim(str) ;
    return detail::string_cast_impl::cast<DecayType>(str) ;
}
4
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.01.2016, 15:29
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Обертка над boost::lexical_cast для работы с unsigned типами (C++):

Обертка для класса TRegistry не работает как положено - C++ Builder
Работая с классом TRegistry сталкиваюсь со следующей проблемой: Пишу вот такую обертку h файл class RegGeneralForm { public: ...

Какие библиотеки нужны для работы с видео avi, flv и для работы с mp3? - C++ Builder
Hello world! Подскажите пожалуйста какие библиотеки нужни мне для работи с видео .avi, flv и т.д и для работи .mp3? Союираюс...

Как настроить проект Visual C++ 2010 для работы с Boost C++? - Visual C++
Скачал boost_1_55_0-msvc-10.0-32.exe, развернул его на диск D в директорию Boost. Структура каталога Boost показана в прикрепленном файле....

Обертка Native для DBX32 (использование в 1С) - Visual C++
Добрый день. Прошу помощи. Есть библиотека DBX32.dll, которая предоставляет возможность работы с PCADом. 1С напрямую с такой работать не...

Обертка над ждущими таймерами: ошибка приведения типа - C++ WinAPI
задумал написать оберточку над ждущими таймерами, вот что вышло пока что: Timer.h #pragma once class Timer { public: ...

Namespace boost не содержит члена lexical_cast - C++
.... #include &quot;boost\lexical_cast.hpp&quot; int main() { ..... m.insert(std::pair&lt;int, std::string&gt;(i,...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
hoggy
31.01.2016, 16:32
  #2

Не по теме:

*утащил в свою коллекцию семплов*

0
Croessmah
Эксперт CЭксперт С++
13209 / 7480 / 841
Регистрация: 27.09.2012
Сообщений: 18,389
Записей в блоге: 3
Завершенные тесты: 1
31.01.2016, 16:35  [ТС] #3
hoggy, стоит ли переделать еще под C++03?
Естественно, без перемещения.
0
hoggy
Нарушитель
6565 / 2746 / 474
Регистрация: 15.11.2014
Сообщений: 6,094
Завершенные тесты: 1
31.01.2016, 16:38 #4
Цитата Сообщение от Croessmah Посмотреть сообщение
стоит ли переделать еще под C++03?
эм, 16 год на дворе.
по-мойму, 03 уже не актуально
0
Croessmah
Эксперт CЭксперт С++
13209 / 7480 / 841
Регистрация: 27.09.2012
Сообщений: 18,389
Записей в блоге: 3
Завершенные тесты: 1
31.01.2016, 16:41  [ТС] #5
Цитата Сообщение от hoggy Посмотреть сообщение
по-мойму, 03 уже не актуально
Поэтому переделал только под 11-ый стандарт.
Тоже думаю, что уже не актуально.
Кому актуально - переделают, покажут )))
1
hoggy
Нарушитель
6565 / 2746 / 474
Регистрация: 15.11.2014
Сообщений: 6,094
Завершенные тесты: 1
31.01.2016, 20:42 #6
Цитата Сообщение от Croessmah Посмотреть сообщение
там std::string, или то, что умеет само кастится к std::string.
Хотя, переделать под std::wstring будет легко

http://rextester.com/RUFT62725
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// =========================================================================================================
// =========================================================================================================
 
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
 
namespace detail
{
    struct string_cast_impl
    {
        template<typename TargetType, typename Str> static
        typename std::enable_if<std::is_unsigned<TargetType>::value, TargetType>::type
        cast(const Str& source)
        {
            if (!source.empty() && source[0] == '-'){
                TargetType result = boost::lexical_cast<TargetType>(source) ;
                return (result!=0) ? throw boost::bad_lexical_cast(),TargetType(0) : result  ;
            }
            return boost::lexical_cast<TargetType>(source);
        }
 
 
        template<typename TargetType, typename Str> static
        typename std::enable_if<!std::is_unsigned<TargetType>::value, TargetType>::type
        cast(const Str& source)
        {
            return boost::lexical_cast<TargetType>(source) ;
        }
    };
}//end of detail
 
 
 
template<typename TargetType, typename StringType>
typename std::decay<TargetType>::type string_cast(StringType&& source)
{
    using CharT = 
        typename std::remove_const<
            typename std::remove_reference<decltype(source[0])>::type
        >::type;
    
    using DecayType = typename std::decay<TargetType>::type ;
    
    //std::string str(std::forward<StringType>(source)) ;
    
    std::basic_string<CharT> str(std::forward<StringType>(source)) ;
    
    boost::trim(str) ;
    return detail::string_cast_impl::cast<DecayType>(str) ;
    
}
 
// =========================================================================================================
// =========================================================================================================
 
 
 
#include <iostream>
 
int main()
{
    std::cout << "Hello, world!\n";
    
    try{
        
        std::cout << string_cast<int>("-100") 
            << std::endl ;
        
        
        std::wcout << string_cast<unsigned>(L"100") 
            << std::endl ;
    
    
        //std::cout << string_cast<unsigned int>("-100") 
          //  << std::endl ;
        
        std::wcout << string_cast<unsigned int>(L"-100") 
            << std::endl ;
        
    }
    catch(const boost::bad_lexical_cast& e)
    {
        std::cout << e.what() << std::endl;
    }
}
1
Croessmah
Эксперт CЭксперт С++
13209 / 7480 / 841
Регистрация: 27.09.2012
Сообщений: 18,389
Записей в блоге: 3
Завершенные тесты: 1
31.01.2016, 21:07  [ТС] #7
hoggy, Я хотел сделать универсальный шаблон,
но решил оставить с кастом к std::string,
т.к. изначально оно для Glib::ustring делалось.
0
hoggy
Нарушитель
6565 / 2746 / 474
Регистрация: 15.11.2014
Сообщений: 6,094
Завершенные тесты: 1
31.01.2016, 21:12 #8
Цитата Сообщение от Croessmah Посмотреть сообщение
Я хотел сделать универсальный шаблон,
но решил оставить с кастом к std::string,
т.к. изначально оно для Glib::ustring делалось.
так ведь оверинжениринга практически нет.
и функциональность не страдает)
0
Croessmah
Эксперт CЭксперт С++
13209 / 7480 / 841
Регистрация: 27.09.2012
Сообщений: 18,389
Записей в блоге: 3
Завершенные тесты: 1
01.02.2016, 03:33  [ТС] #9
Цитата Сообщение от hoggy Посмотреть сообщение
и функциональность не страдает)
Ну вот универсальный код для Glib::ustring не прокатит

О, как!
Немного переделал Ваш и добавил свой.
detail не менял.
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
namespace detail
{
    struct string_cast_impl
    {
        template<typename TargetType, typename Str> static
        typename std::enable_if<std::is_unsigned<TargetType>::value, TargetType>::type
        cast(const Str& source)
        {
            if (!source.empty() && source[0] == '-'){
                TargetType result = boost::lexical_cast<TargetType>(source) ;
                return (result!=0) ? throw boost::bad_lexical_cast(),TargetType(0) : result  ;
            }
            return boost::lexical_cast<TargetType>(source);
        }
 
 
        template<typename TargetType, typename Str> static
        typename std::enable_if<!std::is_unsigned<TargetType>::value, TargetType>::type
        cast(const Str& source)
        {
            return boost::lexical_cast<TargetType>(source) ;
        }
    };
}//end of detail
 
 
template<typename TargetType, typename StringType>
std::enable_if_t<
    !std::is_same<
        std::decay_t<StringType>,
        Glib::ustring
    >::value,
    std::decay_t<TargetType>
>
string_cast(StringType&& source)
{
    using CharT =
        typename std::remove_const<
            typename std::remove_reference<decltype(source[0])>::type
        >::type;
 
    using DecayType = typename std::decay<TargetType>::type ;
 
    //std::string str(std::forward<StringType>(source)) ;
 
    std::basic_string<CharT> str(std::forward<StringType>(source)) ;
 
    boost::trim(str) ;
    return detail::string_cast_impl::cast<DecayType>(str) ;
 
}
 
 
template<typename TargetType, typename StringType>
std::enable_if_t<
    std::is_same<
        std::decay_t<StringType>,
        Glib::ustring
    >::value,
    std::decay_t<TargetType>
>
string_cast(StringType&& source)
{
    using DecayType = typename std::decay<TargetType>::type ;
    std::string str(std::forward<StringType>(source)) ;
    boost::trim(str) ;
    return detail::string_cast_impl::cast<DecayType>(str) ;
}
Добавлено через 7 минут
Блин, ошибся немного. Забыл вырубить шаблон ustring

upd: поменял код
1
Croessmah
Эксперт CЭксперт С++
13209 / 7480 / 841
Регистрация: 27.09.2012
Сообщений: 18,389
Записей в блоге: 3
Завершенные тесты: 1
01.02.2016, 03:33  [ТС] #10
С учетом дополнений из темы Применение is_same для списка типов

Немного доработал код.
Добавил два макроса:
C++
1
2
3
4
5
6
//temporary macros
#define TYPE_LIST_CV(type) type, const type, volatile type, volatile const type
 
#define IGNORING_TYPES              \
    TYPE_LIST_CV(char*),            \
    TYPE_LIST_CV(std::vector<char>)
TYPE_LIST_CV - добавляет к типу квалификаторы
IGNORING_TYPES - список типов, которые должны игнорироваться основным шаблоном

Немного переработал основной шаблон string_cast, для учета указанных игнорируемых типов:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template<typename TargetType, typename StringType>
std::enable_if_t<
    !is_one_same<
        std::decay_t<StringType>,
        IGNORING_TYPES
    >::value,
    std::decay_t<TargetType>
>
string_cast(StringType&& source)
{
    using CharT = std::decay_t<decltype(source[0])> ;
 
    using DecayType = typename std::decay<TargetType>::type ;
 
    std::basic_string<CharT> str(std::forward<StringType>(source)) ;
 
    boost::trim(str) ;
    return detail::string_cast_impl::cast<DecayType>(str) ;
 
}
Теперь, чтобы добавить "особую" версию string_cast для какого-либо типа,
необходимо добавить тип в список игнорируемых
(если требуется игнорировать типы со всеми квалификаторами,
то можно использовать TYPE_LIST_CV), и также
добавить string_cast с этой "особой" реализацией,
добавив в is_one_same соответствующий тип.
Например, вот реализация:
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/*
 * main.cpp
 *
 *  Created on: 29 янв. 2016 г.
 *      author: Croessmah
 */
 
#include <iostream>
#include <vector>
 
 
 
#include <type_traits>
 
 
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
 
 
// =========================================================================================================
// ================================================is_same_list=============================================
// =========================================================================================================
 
 
#include <type_traits>
 
namespace detail
{
 
    template<
        template<class T> class LogicTemplate,
        typename SameType
    >
 
    constexpr bool
    is_same_list_impl()
    {
        return !LogicTemplate<bool>()(true,false) ;
    }
 
 
    template<
    template<class T> class LogicTemplate,
        typename SameType,
        typename FirstType,
        typename ... Args
    >
    constexpr bool
    is_same_list_impl()
    {
        return
                LogicTemplate<bool>()(std::is_same<SameType, FirstType>::value,
                    is_same_list_impl<LogicTemplate, SameType, Args...>()
                ) ;
    }
 
 
 
}//end of detail
 
 
 
 
namespace compile_time
{
    template<class T>
    struct logical_and : public std::binary_function<T,T,bool>
    {
        constexpr bool operator()(const T& first, const T& second) { return first && second ; }
    };
 
 
    template<class T>
    struct logical_or : public std::binary_function<T,T,bool>
    {
        constexpr bool operator()(const T& first, const T& second) { return first || second ; }
    };
}//end of compile_time
 
 
 
 
template<typename SameType, typename ... Args>
struct is_all_same
{
    static constexpr bool value =
            detail::is_same_list_impl<
                compile_time::logical_and,
                SameType, Args...
            >() ;
};
 
 
template<typename SameType, typename ... Args>
struct is_one_same
{
    static constexpr bool value =
            detail::is_same_list_impl<
                compile_time::logical_or,
                SameType, Args...
            >() ;
};
 
 
 
 
 
// =========================================================================================================
// =========================================================================================================
// =========================================================================================================
 
 
// =========================================================================================================
// ================================================string_cast==============================================
// =========================================================================================================
 
 
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
 
 
namespace detail
{
    struct string_cast_impl
    {
        template<typename TargetType, typename StringType> static
        typename std::enable_if<std::is_unsigned<TargetType>::value, TargetType>::type
        cast(const StringType& source)
        {
            if (!source.empty() && source[0] == '-'){
                TargetType result = boost::lexical_cast<TargetType>(source) ;
                return (result!=0) ? throw boost::bad_lexical_cast(),TargetType(0) : result  ;
            }
            return boost::lexical_cast<TargetType>(source);
        }
 
 
        template<typename TargetType, typename StringType> static
        typename std::enable_if<!std::is_unsigned<TargetType>::value, TargetType>::type
        cast(const StringType& source)
        {
            return boost::lexical_cast<TargetType>(source) ;
        }
    };
 
 
}//end of detail
 
 
 
 
//temporary macros
#define TYPE_LIST_CV(type) type, const type, volatile type, volatile const type
 
#define IGNORING_TYPES              \
    TYPE_LIST_CV(char*),            \
    TYPE_LIST_CV(std::vector<char>)
 
 
//Включаем шаблон для всех типов, кроме IGNORING_TYPES
template<typename TargetType, typename StringType>
std::enable_if_t<
    !is_one_same<
        std::decay_t<StringType>,
        IGNORING_TYPES
    >::value,
    std::decay_t<TargetType>
>
string_cast(StringType&& source)
{
    using CharT = std::decay_t<decltype(source[0])> ;
 
    using DecayType = typename std::decay<TargetType>::type ;
 
    std::basic_string<CharT> str(std::forward<StringType>(source)) ;
 
    boost::trim(str) ;
    return detail::string_cast_impl::cast<DecayType>(str) ;
 
}
 
 
 
 
//Включаем шаблон для типов TYPE_LIST_CV(char*)
template<typename TargetType, typename StringType>
std::enable_if_t<
    is_one_same<
        std::decay_t<StringType>,
        TYPE_LIST_CV(char*)
    >::value,
    std::decay_t<TargetType>
>
string_cast(StringType&& source)
{
    using DecayType = typename std::decay<TargetType>::type ;
    std::string str(std::forward<StringType>(source)) ;
    boost::trim(str) ;
    return detail::string_cast_impl::cast<DecayType>(str) ;
}
 
 
 
//Включаем шаблон для типов TYPE_LIST_CV(std::vector<char>)
template<typename TargetType, typename StringType>
std::enable_if_t<
    is_one_same<
        std::decay_t<StringType>,
        TYPE_LIST_CV(std::vector<char>)
    >::value,
    std::decay_t<TargetType>
>
string_cast(StringType&& source)
{
    using DecayType = typename std::decay<TargetType>::type ;
    std::string str(source.begin(), source.end()) ;
    boost::trim(str) ;
    return detail::string_cast_impl::cast<DecayType>(str) ;
}
 
 
 
 
#undef IGNORING_TYPES
#undef TYPE_LIST_CV
 
// =========================================================================================================
// =========================================================================================================
// =========================================================================================================
 
 
 
 
int main(int argc, char ** argv)
{
    std::string str1 ("10") ;
    const char * str2 = "-0" ;
    std::vector<char> vec {'+', '4','0'} ;
    std::cout << string_cast<int>(str1) << std::endl ;
    std::cout << string_cast<unsigned int>(str2) << std::endl ;
    std::cout << string_cast<int>(vec) << std::endl ;
}
http://rextester.com/TZQPR61455

причем, типов, включающих одну такую "специализацию" может быть несколько, например,
C++
1
2
3
4
5
6
7
8
std::enable_if_t<
    is_one_same<
        std::decay_t<StringType>,
        TYPE_LIST_CV(Glib::ustring),
        TYPE_LIST_CV(char*)
    >::value,
    std::decay_t<TargetType>
>
"включит" шаблон для типов TYPE_LIST_CV(Glib::ustring) и TYPE_LIST_CV(char*)
0
Avazart
Эксперт С++
7187 / 5361 / 280
Регистрация: 10.12.2010
Сообщений: 23,655
Записей в блоге: 17
01.02.2016, 18:57 #11

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
эм, 16 год на дворе.
по-мойму, 03 уже не актуально
Да, а С++ до сих пор нет нормальных функций для преобразования ходовых типов с учетом всех возможных вариантов, к примеру локали.



Добавлено через 7 минут
Что касается сути, то не проще ли использовать сначала регулярку потом каст, если регулярка прошла ?
0
hoggy
Нарушитель
6565 / 2746 / 474
Регистрация: 15.11.2014
Сообщений: 6,094
Завершенные тесты: 1
01.02.2016, 19:01 #12
Цитата Сообщение от Croessmah Посмотреть сообщение
С учетом дополнений из темы Применение is_same для списка типов
я так и не понял, что вы пытаетесь построить?

Добавлено через 2 минуты
Цитата Сообщение от Avazart Посмотреть сообщение
Да, а С++ до сих пор нет нормальных функций для преобразования ходовых типов с учетом всех возможных вариантов, к примеру локали.

Не по теме:

хз, что значит:
"учетом всех возможных вариантов, к примеру локали"

0
Avazart
Эксперт С++
7187 / 5361 / 280
Регистрация: 10.12.2010
Сообщений: 23,655
Записей в блоге: 17
01.02.2016, 19:07 #13
Цитата Сообщение от hoggy Посмотреть сообщение
хз, что значит:
"учетом всех возможных вариантов, к примеру локали"
Ну к примеру 1.5 и 1,6 ? как кастануть с учетом десятичного разделителя? Опять же часто бывает нужно работать с датой и временем.
0
hoggy
01.02.2016, 20:51
  #14

Не по теме:

Цитата Сообщение от Avazart Посмотреть сообщение
Ну к примеру 1.5 и 1,6 ? как кастануть с учетом десятичного разделителя? Опять же часто бывает нужно работать с датой и временем.
с датой проще.
можно указывать регулярки для кастов туда/сюда.

с циферками наверное что-то подобное должно быть.

просто это с локалью напрямую никак не связанно.
локали отвечают за национальные символы.
и это - глобальный головняк.
а не только плюсовый.

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



0
Avazart
Эксперт С++
7187 / 5361 / 280
Регистрация: 10.12.2010
Сообщений: 23,655
Записей в блоге: 17
01.02.2016, 21:16 #15
Цитата Сообщение от hoggy Посмотреть сообщение
просто это с локалью напрямую никак не связанно.
локали отвечают за национальные символы.
и это - глобальный головняк.
а не только плюсовый.
Я делаю обычно это в С++Builder так
C++
1
2
3
    TFormatSettings FormatSettings;
    FormatSettings.DecimalSeparator= L',';
    StrToFloat("1,5",FormatSettings);
Кроме того есть еще ф-ция с возвратом значения без выброса исключения TryStrToFloat();
Т.е. сравнительно просто.

http://docwiki.embarcadero.com/Libra...FormatSettings
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.02.2016, 21:16
Привет! Вот еще темы с ответами:

Предусмотреть использование шаблонного класса для работы с различными типами данных - C++
Собственно само задание. Преобразовать квадратную матрицу, осуществив поворот элементов вокруг центра матрицы на 90 градусов против...

Шаблонный класс для работы с разными типами данных и объявление методов в main - C++
есть класс шаблонный, но не могу объявить методы в main и сделать длядругих типов :(когда делала через шаблонные функции, то программа...

Операции над множествами - переписать код для работы с буквами - C++
Здравствуйте,помогите пожалуйста подкорректировать код. В общем есть код, который выполняет различные операции над множествами. Проблема в...

Обертка для list - C++
Есть следующая иерархия классов: class A {}; class B : public A {}; class C : public A {}; class D : public C {}; Я...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
01.02.2016, 21:16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru