首页 > 解决方案 > C++17 to_string() 用逗号转换浮点数

问题描述

这发生在一个大项目中,所以我不能真正发布一个最小的可重现示例,但我会尝试询问。我正在构建一个与我们正在开发的框架集成的基准测试应用程序列表,在其中一个框架上,我们需要进行的转换 (float -> string)to_string似乎重现了一个逗号分隔的结果。

| Monitored values:
| [ my_time_monitor.average = 61720,000000 ]

这是负责的功能:

std::string operating_point_parser::operator()(const int32_t num_threads, const float exec_time_ms) const {
    return "{\"compute\":[{\"knobs\":{\"num_threads\":" + std::to_string(num_threads) + "},\"metrics\":{\"exec_time_ms\":[" + std::to_string(exec_time_ms) + ",0]}}]}";
}

因为正如我所说的,其他应用程序正在调用相同的确切函数,而这些应用程序没有显示出这种意外行为,我的猜测是一些内部编译标志搞砸了。

set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -DENABLE_THREADS  -DHAVE_RANDOM -DHAVE_UNISTD_H  -DHAVE_SYS_FILE_H -DHAVE_SYS_MMAN_H -DHAVE_CONFIG_H -DVIPSDATASET_PATH=\"\\\"${CMAKE_CURRENT_SOURCE_DIR}/dataset/orion_18000x18000.v\\\"\"" )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_RANDOM -DHAVE_UNISTD_H -DIM_PREFIX=\"\\\"${CMAKE_CURRENT_SOURCE_DIR}/dataset\\\"\" -DIM_EXEEXT=\"\\\"\\\"\" -DIM_LIBDIR=\"\\\"${CMAKE_INSTALL_PREFIX}/lib\\\"\" -DGETTEXT_PACKAGE=\"\\\"vips7\"\\\" -DHAVE_SYS_FILE_H -DHAVE_SYS_MMAN_H -DHAVE_CONFIG_H")

如果您想查看完整的应用程序代码,请点击此处的链接。被operating_point_parse::operator()称为 inside margot::compute::push_custom_monitor_values()

标签: c++string

解决方案


如https://en.cppreference.com/w/cpp/string/basic_string/to_string的注释中所述,to_string依赖于当前语言环境进行格式化:

std::to_string 依赖于当前语言环境进行格式化,因此从多个线程并发调用 std::to_string 可能会导致调用的部分序列化。C++17 提供 std::to_chars 作为更高性能的独立于语言环境的替代方案。

所以,如果你想用点而不是逗号,你必须调整当前的语言环境。

std::locale::global(...)或者,您可以使用 a和 imbue() 仅在该流上使用语言环境来代替更改全局语言环境stringstream,例如。

stringstream ss;
ss.imbue( locale you want )
ss << ... write what you need
ss.str(); // get formatted string

推荐阅读