我正在为 ARM Cortex 编写代码。处理器周期非常宝贵,我正在努力从编译器中获得尽可能多的工作。我对 UART_WriteStr() 进行了多次调用,其中大部分使用字符串文字。
main() {
...
UART_WriteStr("Initialization complete");
...
}
目前 UART_WriteStr() 看起来像这样:
void UART_WriteStr(boost::string_view data) {
uint32_t timeout = UINT32_MAX;
for (auto el: data) {
//UART peripheral control logic
}
}
(我的 ARM 编译器无法处理 C++17 或更高版本,这就是我使用 boost::string_view 的原因)
这非常好,string_view 获取指针并且不进行任何新的分配。但我可以在 string_view 构造函数的程序集中看到,它通过迭代字符串查找空字符来确定长度。我发现这很烦人,编译器知道长度,而 string_view 有一个需要指针和长度的构造函数。但如何使用该构造函数呢?
我可以这样做:
int constexpr const_cstr_length(const char* str) {
return *str ? 1 + const_cstr_length(str + 1) : 0;
}
boost::string_view constexpr CCstr(const char * msg) {
return {msg, static_cast<size_t>(const_cstr_length(msg))};
}
main() {
...
UART_WriteStr(CCstr("Initialization complete"));
...
}
但是为什么我必须用特殊的函数来装饰我的字符串呢?为什么我不能重载 UART_WriteStr() 来获得我想要的行为?
我尝试过这个:
static inline void UART_WriteStr(const char * data) {
UART0_WriteFIFO(boost::string_view(data, const_cstr_length(data)));
}
但是 data
不再是常量,const_cstr_length() 再次陷入执行时间循环。
如何重载 UART_WriteStr(),以便可以从编译时间长度创建 boost::string_view?由于 C/C++ 处理函数参数中字符串的方式,我正准备宣布这是不可能的,但 CCstr() 给了我希望,我错了。
最佳答案
另一种选择是使用模板:
template <std::size_t N>
void UART_WriteStr(const char (&data)[N]) {
UART_WriteStr(boost::string_view(data, N - 1));
}
注意:字符串内部可能包含 '\0'
(作为 ""_bs
解决方案)。
关于c++ - 字符串文字,让编译器计算 string_view 构造函数的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76202201/