我有一个常量字符串值
std::string name_to_use = "";
我只需要在一个地方使用此值,并在其上调用以下函数
std::wstring foo (std::string &x) {...};
// ...
std::wstring result = foo (name_to_use);
我不能简单地声明变量并在函数调用中使用字符串文字,但为了便于配置name_to_use
我决定在文件开头声明。
现在,因为我没有真正修改< code>name_to_use,所以我想为什么不使用< code>#define预处理指令,这样我就不必在主程序连续运行(显示GUI)时将name_to_use作为常量存储在内存中的任何位置。
它工作得很好,但后来我遇到了constexr
。stackoverflow上的一位用户说使用它而不是#定义
,因为它是一个更安全的选项。
然而,d::字符串name_to_use
在这种情况下仍然会泄漏内存,因为它实际上并没有用值替换出现的name_to_use
,而是保存了在编译时计算的对它的引用(无论如何,如果我没有弄错的话,这并没有给我带来任何好处?)。
如果你#define
它到“”
,那么在每次调用时都会有一个从c-string到std::string
的转换,这是非常低效的。但是,您可以(通常)将宏定义作为参数传递给编译器,这有助于自定义。即使在这种情况下,编写静态 constexpr std::string name_to_use
也是有意义的。
with < code > static const expr STD::string name _ to _ use =...;,转换的问题就消失了(很可能在编译时完成)。不要期望编译器不做优化——如果它是一个编译时字符串,可能会发生整个函数都被优化掉的情况(但是对象仍然存在,代码将遵守假设规则)。
要将两者结合起来,您可以这样做:
#ifdef NAME_TO_USE
constexpr const std::string = # NAME_TO_USE;
#else
constexpr const std::string = "";
#endif
另外,正如其他人所说,请考虑 std::string_view
以避免分配。
用户说得很好,你确实理解对了。
使用 constexpr
方法将在宏在编译时替换自身时分配一个常量。第一个的唯一好处是它是类型的,并且可以在编译代码时使您的代码更安全一些。
话虽如此,选择权在你。您想要一个在运行时不添加任何操作的非类型宏,还是一个在解析时使用少量内存的类型常量?