提问者:小点点

#define或constexpr,在这里哪个更适合最大效率?


我有一个常量字符串值

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,而是保存了在编译时计算的对它的引用(无论如何,如果我没有弄错的话,这并没有给我带来任何好处?)。


共2个答案

匿名用户

如果你#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 方法将在宏在编译时替换自身时分配一个常量。第一个的唯一好处是它是类型的,并且可以在编译代码时使您的代码更安全一些。

话虽如此,选择权在你。您想要一个在运行时不添加任何操作的非类型宏,还是一个在解析时使用少量内存的类型常量?