c++ - 字符串文字,让编译器计算 string_view 构造函数的长度

标签 c++ c++14

我正在为 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/

相关文章:

c++ - 未调用模板化函数

c++ - CMAKE 链接外部 c 库

c++ - 如何正确存储/传递接口(interface)类型的变量(现代 C++)?

c++ - 将非算术类型作为参数传递给 cmath 函数是否有效?

c++ - 从 braced-init-list 初始化私有(private)聚合

c++ - ShellExecuteW 在 Windows 8.1 上运行不正常?

c++ - R Makevars 文件没有正确覆盖 g++

C# 程序员的 C++ 调试帮助

c++ - 将代码转换为 constexpr

c++ - 为什么这个程序在 C++14 中编译得很好,但在 C++11 编译器中却不行?