#define还是constexpr,哪一个更适合在这里实现最大效率



我有一个常量字符串值

std::string name_to_use = "";

我只需要在一个地方使用这个值,在上调用下面的函数

std::wstring foo (std::string &x) {...};
// ...
std::wstring result = foo (name_to_use);

我可以简单地不声明变量,而是在函数调用中使用字符串文字,但为了方便配置name_to_use,我决定在文件开头声明。

现在,由于我并没有真正修改name_to_use,我想为什么不使用#define预处理指令,这样当主程序连续运行(显示GUI(时,我就不必将name_to_use作为常量存储在内存中的任何位置。

它运行良好,但后来我遇到了constexpr。stackoverflow上的一位用户表示,使用它而不是#define,因为它是一个更安全的选择。

然而,在这种情况下,constexpr std::string name_to_use仍然会泄漏内存,对吧?因为它实际上并不是用值替换name_to_use的出现,而是在编译时保留对它的引用(如果我没有错的话,这在这里不会给我带来任何好处?(。

如果将其#define转换为"",则在每次调用时都会有从c-string到std::string的转换,这是非常低效的。不过,您可以(通常(将宏定义作为参数传递给编译器,这有助于自定义。即使在这种情况下,编写static constexpr std::string name_to_use也是有意义的。

有了static constexpr 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方法将分配一个常量。第一种方法的唯一好处是它是类型化的,并且在编译时可以使代码更安全

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

最新更新