I would like to remove the reliance of #define macros in my code, and I'm unable to achieve the same functionality with constexpr.
To be practical, consider the following example:
#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
};
};
I've learned the hard way that fmt::format() function is not a constexpr function and it's only a runtime function. I was expecting that I could it in the code to be more expressive, but I can't. So I've tried using std::string, but again I got the same exact results after changing the code to something like:
#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
};
};
So what are my misunderstandings:
- That I could use
fmtin aconstexprcontext. Which is untrue. std::stringwith proper support fromlibstdc++should beconstexprto evaluate string operations at compile time, but it does not seems to be the case.- I misunderstood the utility of
__cpp_lib_constexpr_stringmacro on the Standard Library. - That C++20 would give more flexibility with text manipulation in a
constexprcontext.
I already done my homework and came across other questions of Stack Overflow_ about similar issues, or how to use std::string in a constexpr context:
- Difference between `constexpr` and `#define`
- How does constexpr std::string in C++20 work?
- Is it possible to use std::string in a constexpr?
But none of them answered my question with clarity: How can I concatenate two given strings at compile time to properly get rid of #define macros in the code?
This seems to be trivial, since both strings are known at compile time, and they are also constexpr. The final goal would be to have a third constexpr const char* with the content: CloysterHPC Installer without using any #define macros on the code.
How can I achieve this? Is that even possible in the current state of the language? Should I continue using the macro? My current setup is GCC 12.1.1 with default libstdc++ on a RHEL 8.7 system:
gcc-toolset-12-12.0-5.el8.x86_64
gcc-toolset-12-libstdc++-devel-12.1.1-3.4.el8_7.x86_64
PS: Please note that sometimes I mentioned strings in the question knowing that they aren't std::string, but actually const char*. It was just a language convention and not a type definition.