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
fmt
in aconstexpr
context. Which is untrue. std::string
with proper support fromlibstdc++
should beconstexpr
to evaluate string operations at compile time, but it does not seems to be the case.- I misunderstood the utility of
__cpp_lib_constexpr_string
macro on the Standard Library. - That C++20 would give more flexibility with text manipulation in a
constexpr
context.
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.