Я пытаюсь преобразовать числовые c типы в строковые представления фиксированной длины с начальными нулями (используется в GUI, который может иметь дело только со строками - и лексикографическая c сортировка чисел действительно неудобна).
Вместо создания строки в том месте, где она требуется, я полагаю, что можно создать отличный шаблон для использования другими людьми, который также работает с различными типами арифметики c.
template <typename T, typename std::enable_if<std::is_arithmetic<T>::value, T>::type* = nullptr>
std::string arithmeticToMaxLengthString(const T& value)
{
std::string number, result;
number = std::to_string( value );
result = lpad( '0', std::numeric_limits<decltype(value)>::digits10 + 1, number );
return result;
}
std::string lpad( char filler, std::string::size_type length, const std::string& input)
{
std::string result;
if( input.length() < length )
{
result.append( lenght - input.lenght(), filler ).append( input );
return result;
}
return input;
}
Пока все хорошо. Он компилируется, и я могу его использовать. НО:
Когда я попытался использовать его, я получил сюрприз. Вызов этой функции с int32_t, равным
typedef int int32_t;
, который имеет значение 100, в результате получается строка "100", длина 3.
Я почти уверен, что нет другого шаблона с такое плохое имя существует в кодовой базе (у меня есть поиск по всем этим и всем связанным библиотекам), но я не могу понять, что не так с кодом, который я создал. Чтобы проверить правильность кода, я просто скопировал его в место, где он вызывается, что теперь в основном выглядит следующим образом:
myDataClass{
int32_t quantity;
std::string numberAsString;
}
void setNumberString( myDataClass data )
{
std::string result = arithmeticToMaxLengthString( data.quantity );
std::string reference = lpad( '0', std::numeric_limits<decltype(value)>::digits10 + 1, std::to_string(data.quantity) );
std::cout << "quantity<" << data.quantity << "> numericLimits<" << std::numeric_limits<decltype(value)>::digits10 + 1 << ">" << std::endl;
std::cout << "result template: length<" << result.lenght() << "> content<" << result << ">" << std::endl;
std::cout << "result reference: length<" << reference.lenght() << "> content<" << reference << ">" << std::endl;
}
Теперь, насколько я понимаю, шаблон "arithmeticToMaxLengthString" вызывается с int32_t как тип аргумента, который является нормальным int, где «numeric_limits :: digits10 + 1» дает мне 10. Но когда эта функция теперь вызывается с количеством, скажем, 100, результаты отличаются.
quantity<100> numericLimits<10>
result template: length<3> content<100>
result reference: length<10> content<0000000100>
Я что-то упускаю из-за шаблонов, enable_if или numeric_limits? Чем шаблон отличается (кроме очевидного enable_if)?