Home > OS >  Can I use a const char* or std::string variable containing grammar as argument to libfmt?
Can I use a const char* or std::string variable containing grammar as argument to libfmt?

Time:02-24

Hopefully this is a silly question. I have the following code:

#include <iostream>
#include <fmt/format.h>
#include <string>
int main(){
 double f = 1.23456789;
 std::cout << fmt::format( "Hello {:f} how are you?\n", f ) << "\n";
 return 0;
}

And this works as expected --Hello 1.234568 how are you?

But if I want to encapsulate the string passed into fmt::format as a variable, I run into a compiler error:

#include <iostream>
#include <fmt/format.h>
#include <string>
int main() {
 double f = 1.23456789;
 const char* m = "Hello {:f} how are you?\n"; //can't be constexpr, generated at run time
 std::cout << fmt::format( m, f ) << "\n";
 return 0;
}

However, on MSVC 2022 using #include <format>, this works perfectly...

#include <iostream>
//#include <fmt/format.h>
#include <format>
#include <string>
int main() {
 double f = 1.23456789;
 const char* m = "Hello {:f} how are you?\n";
 std::cout << std::format( m, f ) << "\n";
 return 0;
}

Is this possible using libfmt? It appears libfmt wants a constexpr value passed in whereas msvc's <format> evaluates this at runtime. What silly mistake am I making here?

CodePudding user response:

Since libfmt 8.1, you can wrap the format string in fmt::runtime to enable runtime formatting:

#include <iostream>
#include <fmt/format.h>
#include <string>
int main() {
 double f = 1.23456789;
 const char* m = "Hello {:f} how are you?\n"; //can't be constexpr, generated at run time
 std::cout << fmt::format(fmt::runtime(m), f ) << "\n";
 return 0;
}

CodePudding user response:

You can use fmt::vformat for run-time string

#include <iostream>
#include <fmt/format.h>
#include <string>
int main() {
 double f = 1.23456789;
 const char* m = "Hello {:f} how are you?\n"; //can't be constexpr, generated at run time
 std::cout << fmt::vformat( m, fmt::make_format_args(f)) << "\n";
 return 0;
}

Demo

Is this possible using libfmt? It appears libfmt wants a constexpr value passed in whereas msvc's evaluates this at runtime.

P2216R3 makes std::format only accept compile-time format string. If you want to use run-time format string you need to use std::vformat. I suspect this is just because MSVC has not implemented P2216R3 yet.

  • Related