- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想做的是创建:
template<Args... args)>
int println(Args...) {
// implementation which calls:
// printf("<string literal format string at compile time>", args...);
// additional perk would be compile time type checking
// I expect to provide a format string for each type by some template
// specialization.
}
我一直在用编译时字符串文字分析两个有趣的工作:
编译时内存对齐的字符串文字
100% constexpr 字符串实现
http://sourceforge.net/p/constexprstr/code/HEAD/tree/no-pp-constexpr_string.cpp
基本上,我或多或少能够静态推断格式所需字符串文字的长度,但仅此而已,因为编译器拒绝将我的工作视为 constexpr。另一个大问题是,当使用上述链接中的 constexpr 字符串时,编译器永远无法推断出结果字符串的大小。
我越努力实现这一点,我的无知就越多地超过了我的热情。如果有任何提示和/或代码示例可以解决执行此类实现时的部分或全部问题,我将不胜感激。
注意:我不是在寻找有关使用不同形式的日志记录(例如通过 cout)的建议。
注意 2:不应使用任何 std::string,因为它们是运行时
注意 3:通常所有类型安全的 printfs 都使用不同的方法,我很熟悉这可以通过多次调用 printf
轻松完成。我想在一次通话中完成。我也知道可以逐步构建缓冲区,但这个问题是关于构建格式字符串的。 :)
更新:基本上代码需要实现的部分是
constexpr const char* formatString = build_compile_time_format_string(args...);
// build_compile_time_format_string(3, "hi", -3.4)
// should evaluate to "%d %s %f"
// or to "%d hi %f"
最佳答案
很简单,我们将构建一个带有 "%d"
或任何类型的编译时字符串,连接一个 '\n'
,然后去掉前导空格。
首先,我们需要一个用作编译时字符串的类型:
template<char...cs> struct compile_time_string
{static constexpr char str[sizeof...(cs)+1] = {cs...,'\0'};};
template<char...cs>
const char compile_time_string<cs...>::str[sizeof...(cs)+1];
并且为了防止中间步骤生成无意义的缓冲区,一个 stringbuilder:
template<char...cs> struct compile_time_stringbuilder
{typedef compile_time_string<cs...> string;};
//remove leading spaces from stringbuilder
template<char...cs> struct compile_time_stringbuilder<' ', cs...>
{typedef typename compile_time_stringbuilder<cs...>::string string;};
然后,您需要采用 compile_time_stringbuffer
和类型的函数,并返回带有 "%d"
或任何附加内容的 compile_time_stringbuffer
.由于我们正在处理类型,所以我什至懒得定义函数。请注意,我的“结束”特化为您连接了一个 '\n'
字符
template<char...cs, class...Ts>
compile_time_stringbuilder<cs...,'\n'> concatenate_compile_time_format_string(compile_time_stringbuilder<cs...>);
template<char...cs, class...Ts>
auto concatenate_compile_time_format_string(compile_time_stringbuilder<cs...>,int,Ts...args)
-> decltype(concatenate_compile_time_format_string(compile_time_stringbuilder<cs...,' ','%','d'>(),args...));
template<char...cs, class...Ts>
auto concatenate_compile_time_format_string(compile_time_stringbuilder<cs...>,const char*,Ts...args)
-> decltype(concatenate_compile_time_format_string(compile_time_stringbuilder<cs...,' ','%','s'>(),args...));
template<char...cs, class...Ts>
auto concatenate_compile_time_format_string(compile_time_stringbuilder<cs...>,double,Ts...args)
-> decltype(concatenate_compile_time_format_string(compile_time_stringbuilder<cs...,' ','%','f'>(),args...));
最后,一个有用且易于使用的界面。
template<class...Ts>
constexpr const char* build_compile_time_format_string()
{
using compile_time_stringbuilder = decltype(concatenate_compile_time_format_string(compile_time_stringbuilder<>(),std::declval<Ts>()...));
using compile_time_string = typename compile_time_stringbuilder::string;
return compile_time_string::str;
}
它是这样使用的:
template<class...Args>
void println(Args...args) {
constexpr const char* formatString = build_compile_time_format_string<Args...>();
std::cout << formatString;
}
这是执行证明:http://coliru.stacked-crooked.com/a/16dc0becd3391aaa
完全没有必要,充实 compile_time_string
以大致匹配 const std::string
的接口(interface)可能会很有趣,如下所示:
template<char...cs> struct compile_time_string
{
static constexpr char str[sizeof...(cs)+1] = {cs...,'\0'};
constexpr size_t size() {return sizeof...(cs);}
constexpr char* begin() {return str;}
constexpr char* end() {return str+sizeof...(cs);}
};
关于用于调用 printf 的 C++11 编译时格式字符串文字构造,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24152042/
我想知道以下语句在 C 中会打印什么? printf("hello\n") || (printf("goodbye\n") || printf("world\n")); 我通常习惯于使用“cout”在
这是我目前正在学习的系统编程类(class)的幻灯片: catch_child 是 SIGCHLD 处理程序。输出与代码如何对应?为什么没有打印一些“Child #x started”消息? 最佳答案
这有点像拼图……我刚刚又回到了C,打算这次掌握它。所以我一直在阅读 The C Programming Language ,我得到了这个声明: Among others, printf also re
如何使用 printf 在字符串末尾附加空格? 我找不到任何在右侧附加空格的示例。 A similar question我发现使用 printf改为在字符串的左侧添加空格。 最佳答案 使用负数左对齐(
我想通过 usart 从 stm32f405 注销。 在我的 syscall.c 文件中,我实现了通过 usart 打印的功能: int _write(int file, char *ptr, int
我想定义一个记录器函数,比如 myPutStrLn = putStrLn . (++) "log: " main = do myPutStrLn "hello" 这很好。现在我想用 printf 格式
Printf module API详细介绍了类型转换标志,其中: %B: convert a boolean argument to the string true or false %b: conv
@H2CO3 这是我的主要代码: #pragma OPENCL EXTENSION cl_ amd_ printf : enable #define PROGRAM_FILE "matvec.cl"
Printf module API详细介绍了类型转换标志,其中: %B: convert a boolean argument to the string true or false %b: conv
您可以使用 printf 字段宽度说明符截断字符串: printf("%.5s", "abcdefgh"); > abcde 不幸的是,它不适用于数字(将 d 替换为 x 是相同的): printf(
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 4 年前。 Improve th
我遇到了我见过的最奇怪的错误之一。 我有一个简单的程序,可以打印多个整数数组。 对数组进行排序,然后打印...... place_in_buf(n100, 100); insertion(10
我的程序是每隔一段时间获取文件大小并显示它以记录任何更改。由于某种原因,执行下面的代码挂起,只为我提供了一个光标。没有打印或显示任何内容。 代码: #include #include #inclu
printf("It is currently %s's turn.\n", current->name); 我想知道为什么在 %s 之后打印出额外的换行符。我知道C 中的字符串总是以\0 结尾。没有
这个问题已经有答案了: printf anomaly after "fork()" (3 个回答) fork() in c using printf [duplicate] (2 个回答) 已关闭 9
我对编程很陌生。 我正在尝试编写一个程序,从数组中调用水果的价格。但我希望代码在写价格之前也写水果的名称。如果我键入 2,如何使输出为“Orange price : 10”而不仅仅是 price :
这个问题在这里已经有了答案: How do I print a non-null-terminated string using printf? (2 个答案) 关闭 7 年前。 例如,我有一个字符
我有一个 atmel UC3-L0 和罗盘传感器。现在我安装 AtmelStudio 并将一些演示代码下载到电路板中。但是我不知道演示代码中的函数 printf 会在哪里出现数据。我应该如何获取数据?
我有一个 atmel UC3-L0 和罗盘传感器。现在我安装 AtmelStudio 并将一些演示代码下载到电路板中。但是我不知道演示代码中的函数 printf 会在哪里出现数据。我应该如何获取数据?
嗨,我是 C 世界的新手,我的代码确实有些奇怪。目标是创建一个函数,可以在开头和结尾处用空格和/或制表符修剪字符串。我无法使用字符串库。 问题是我的代码中有一个 printf 只是用于测试,它的工作非
我是一名优秀的程序员,十分优秀!