c++ - 将数字转换为填充字符串

标签 c++ c++11 templates enable-if numeric-limits

我正在尝试将数字类型转换为带有前导“0”的固定长度字符串表示(在只能处理字符串的 GUI 中使用 - 并且数字的字典排序真的很尴尬)。

与其在需要的地方创建字符串,我认为应该可以制作一个很好的模板供其他人使用,该模板也适用于不同的算术类型。

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)?

最佳答案

您的问题发生是因为您正在传递对 arithmeticToMaxLengthString 的引用功能。出于另一个答案中列出的原因 here , std::numeric_limits不适用于引用。

因此,我建议您使用模板类型 T用于获取数值限制而不是使用 decltype(value) :

result = lpad('0', std::numeric_limits<T>::digits10 + 1, number);

它不仅解决了问题,而且看起来也更加优雅。

关于c++ - 将数字转换为填充字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60252533/

相关文章:

python - 使用 conda 安装 glpk cvxopt

c++ - 文件在多个程序中持续无法打开

django - Django 模板中的 TinyMCE

c++ - 如何专门化模板类成员函数?

templates - 在 Ansible 角色中渲染特定的配置文件模板

c++ - 为 Raspberry Pi 交叉编译 rethinkdb

c++ - 将 OpenCV 原始指针和 lambda 用于直方图的不同结果

c++ - 模板类中的尾随返回类型(GNU 和 Microsoft 编译器之间的矛盾)

c++ - GCC constexpr constexpr 函数中的 lambdas 和编译时的评估

c++ - 与参数中的默认值聚合