提问者:小点点

在必须连接两个const char*变量的情况下,如何避免在C中使用#定义宏?


我想在我的代码中删除对#定义宏的依赖,并且我无法使用constexr实现相同的功能。

实际上,考虑下面的例子:

#define PRODUCT_NAME "CloysterHPC"
constexpr const char* productName = PRODUCT_NAME;

class Newt : public View {
private:
    struct TUIText {

#if __cpp_lib_constexpr_string >= 201907L
        static constexpr const char* title = 
            fmt::format("{} Installer", productName).data();
#else
        static constexpr const char* title = PRODUCT_NAME " Installer";
#endif

    };
};

我已经学会了 fmt::format() 函数不是一个 constexpr 函数,它只是一个运行时函数。我本以为我可以在代码上更具表现力,但我不能。所以我尝试使用 std::string,但在将代码更改为以下内容后,我再次得到了相同的确切结果:

#define PRODUCT_NAME "CloysterHPC"
constexpr const char* productName = PRODUCT_NAME;

class Newt : public View {
private:
    struct TUIText {

#if __cpp_lib_constexpr_string >= 201907L
        static constexpr const char* title = std::string{
            std::string{productName} + std::string{" Installer"}}.data();
#else
        static constexpr const char* title = PRODUCT_NAME " Installer";
#endif

    };
};

那么我的误解是什么:

  1. 我可以使用fmt上下文中。这是不真实的。
  2. std::stringlibstdc的适当支持下,应该是constexr以在编译时评估字符串操作,但似乎并非如此。
  3. 我误解了__cpp_lib_constexpr_string宏在标准库上的实用程序。
  4. C 20将提供更大的灵活性,可以在constrexr上下文中进行文本操作。

我已经做了我的功课,遇到了StackOverflow关于类似问题的其他问题,或者如何使用std::字符串Constrexr上下文中:

  • 'Constrexr'和'#定义'之间的区别
  • C 20中的d::字符串,它是如何工作的?
  • 是否有可能使用std::字符串在一个常量?

但是他们都没有清楚地回答我的问题:如何在编译时连接两个给定的字符串,以正确地去除代码中的< code>#define宏?

这似乎微不足道,因为这两个字符串在编译时都是已知的,而且它们也是constexpr。最终目标是在内容中使用第三个constexpr const char*CloysterHPC Installer,而不在代码上使用任何#define宏。

如何做到这一点?在目前的语言状态下,这是可能的吗?我应该继续使用宏吗?我当前的设置是GCC 12.1.1,在RHEL 8.7系统上使用默认libstdc

gcc-toolset-12-12.0-5.el8.x86_64
gcc-toolset-12-libstdc++-devel-12.1.1-3.4.el8_7.x86_64

谢谢。

PS:请注意,有时我在问题中提到字符串,知道它们不是std::string,但实际上是constchar*。这只是一种语言惯例,而不是类型定义。


共0个答案