我一直在尝试使用std::formatC++20中包含的函数。据我所知,clang 14 应该支持此功能,但由于某种原因我收到以下错误:no member named 'format' in namespace 'std'。根据cppreference 的编译器支持图表,clang 应该支持文本格式,但我仍然收到此错误。我不知道问题是什么。
我有以下代码:
#include <print>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3};
std::println("{}", v);
}
Run Code Online (Sandbox Code Playgroud)
在这产生的众多错误中,有(clang++ -std=c++23 -stdlib=libc++,https://godbolt.org/z/3z9Tseh37):
[...]/format_arg_store.h:167:17: error: static assertion failed due to [...]
167 | static_assert(__arg != __arg_t::__none, "the supplied type is not formattable");
| ^~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
这让我很困惑,因为根据cppreference C++23 编译器支持页面,libc++ 支持std::println并实现P2286: Formatting Ranges。
我做错了什么还是这是标准库错误?
最近我发现以下代码在几个主要编译器上编译,然后在运行时抛出:
std::cout << std::format("{:*<{}}", 10, "Hello") << std::endl;
Run Code Online (Sandbox Code Playgroud)
terminate called after throwing an instance of 'std::format_error'
what(): format error: argument used for width or precision must be a non-negative integer
Run Code Online (Sandbox Code Playgroud)
它会抛出异常,因为“10”应该出现在“Hello”之后,而不是之前。
但明显的问题是:为什么它在编译时没有失败?我的理解是,这些参数将在编译时进行类型检查,显然 aconst char*不能用作宽度说明符。为什么这不是编译错误?
如果您不明白为什么这会令人困惑,请知道 的第一个参数std::format()是 type std::format_string<...>。此类型在编译时采用字符串文字/字符串视图(由于其consteval构造函数),并在编译时读取给定字符串的内容以查看格式参数是否与格式字符串匹配。因此,保证不会std::format("{}");编译,因为字符串“{}”在编译时被读取为格式说明符,但类型列表显示没有传递任何参数,那么该空间中会放入什么?
std::format有一个(编译时和运行时)格式字符串验证,但此验证中不包括的一件事是是否有足够的{}占位符用于所有参数(过多的参数将被默默忽略)。
我认为这在某些罕见的情况下可能很有用(例如,如果您生成格式字符串),但我不需要它,并且因此我遇到了一些错误。
我可以做些什么来检查这个编译时间吗?可能通过包装std::format我自己的函数。
例子:
#include <format>
#include <iostream>
int main()
{
std::cout << std::format("{} {}", 1, 2, 3, 4, 5) << '\n'; // Prints `1 2`, no error!
}
Run Code Online (Sandbox Code Playgroud)
注意: std::format 确实有编译时格式字符串验证。他们只是不检查这个具体问题(过多的争论)。
我是 C++ 新手。我试图将当前日期和时间存储为字符串变量。
在这个问题上,我找到了答案,并安装了该date.h库。
但是,当我尝试使用提供的代码时,遇到了错误:
命名空间“std”没有成员“format”
尽管位于#include <format>脚本的顶部。
我怎样才能解决这个问题?
我正在 Windows 10 上使用 Visual Studio 2022,如果有帮助的话。
这是我的代码:
#include <iostream>
#include <chrono>
#include <date.h>
#include <type_traits>
#include <format>
int main()
{
std::cout << "The current time is ";
auto start_time = std::format("{:%F %T}", std::chrono::system_clock::now());
static_assert(std::is_same_v<decltype(start_time), std::string>{});
std::cout << start_time << "\n";
}
Run Code Online (Sandbox Code Playgroud) 我想消除代码中对 #define 宏的依赖,但我无法使用constexpr.
为了实用,请考虑以下示例:
\n#define PRODUCT_NAME "CloysterHPC"\nconstexpr const char* productName = PRODUCT_NAME;\n\nclass Newt : public View {\nprivate:\n struct TUIText {\n\n#if __cpp_lib_constexpr_string >= 201907L\n static constexpr const char* title =\n fmt::format("{} Installer", productName).data();\n#else\n static constexpr const char* title = PRODUCT_NAME " Installer";\n#endif\n\n };\n};\nRun Code Online (Sandbox Code Playgroud)\n我经历了惨痛的教训才知道fmt::format()函数不是constexpr函数,它只是一个运行时函数。我本以为我可以在代码中更具表现力,但我不能。所以我尝试使用std::string,但在将代码更改为类似以下内容后,我再次得到了相同的确切结果:
#define PRODUCT_NAME "CloysterHPC"\nconstexpr const char* productName = PRODUCT_NAME;\n\nclass Newt : public View {\nprivate:\n struct TUIText {\n\n#if __cpp_lib_constexpr_string >= 201907L\n static constexpr const char* title = …Run Code Online (Sandbox Code Playgroud) 假设我想std::formatter绕过直接使用 来格式化单个对象std::format。我怎么做?
根据Formatter,我需要调用.format(value, format_ctx),其中format_ctx是std::format_contextor std::basic_format_context<...>。但我如何构建这个上下文呢?
该标准似乎没有提供一种构建方法。查看libstdc++ 源代码, 的成员变量basic_format_context都是私有的,没有非默认构造函数,并且如果不是friend.
这是否意味着std::formatter不可能按设计手动使用?
我为什么要这样做?
我想使用“调试格式”( "{?:}") 来格式化一个值(如果支持的话),回退到常规"{}".
检查支持的方法似乎是requires(std::formatter<T> f){f.set_debug_format();},我想如果我已经直接与格式化程序交互,我不妨只使用格式化程序本身。
我正在寻找一种快速而简洁的方式来打印一个漂亮的表格格式,正确对齐单元格.
在c ++中是否有一种方便的方法来创建具有一定长度的子串的字符串,如python格式
"{:10}".format("some_string")
Run Code Online (Sandbox Code Playgroud) 我正在尝试在我的 C++ 项目中使用 fmt ( https://github.com/fmtlib/fmt ) 格式化标头库。
我已在主文件顶部添加了核心头文件的路径,如下所示:
#include "../third_party/fmt/core.h"
但是当我尝试调用任何函数时,例如:
string message = fmt::format("The answer is {}", 42);
我收到以下错误:
Undefined symbols for architecture x86_64:
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > fmt::v5::internal::vformat<char>(fmt::v5::basic_string_view<char>, fmt::v5::basic_format_args<fmt::v5::buffer_context<char>::type>)", referenced from:
std::__1::basic_string<std::__1::enable_if<internal::is_string<char [17]>::value, fmt::v5::internal::char_t<char [17]>::type>::type, std::__1::char_traits<std::__1::enable_if<internal::is_string<char [17]>::value, fmt::v5::internal::char_t<char [17]>::type>::type>, std::__1::allocator<std::__1::enable_if<internal::is_string<char [17]>::value, fmt::v5::internal::char_t<char [17]>::type>::type> > fmt::v5::format<char [17], int>(char const (&) [17], int const&) in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** …Run Code Online (Sandbox Code Playgroud) 我想使用fmt库格式化浮点数。
我尝试用小数点分隔符','格式化浮点数,并尝试此操作未成功:
#include <iostream>
#include <fmt/format.h>
#include <fmt/locale.h>
struct numpunct : std::numpunct<char> {
protected:
char do_decimal_point() const override
{
return ',';
}
};
int main(void) {
std::locale loc;
std::locale l(loc, new numpunct());
std::cout << fmt::format(l, "{0:f}", 1.234567);
}
Run Code Online (Sandbox Code Playgroud)
输出为1.234567。我想要1,234567
我浏览了fmt库的源代码,并认为小数点分隔符已硬编码为浮点数,并且不遵守当前语言环境。