Looking at the documentation, I don’t understand why std::make_format_args() takes a reference and not a const reference?
My goal is to implement something like:
#include <format>
template <class... Args>
inline static std::string format(const std::string_view field, Args&&... args)
{
return std::vformat(field, std::make_format_args(std::forward<Args>(args)...));
}
And being able to pass const std::string& as input in args, but it seems like std::make_format_args() expects a non-const reference.
I get an error:
A non-const reference may only be bound to an lvalue C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.40.33807\include\format(3713): note: see declaration of 'std::make_format_args'
note: while trying to match the argument list '(_Ty, const std::string, _Ty, _Ty)'
>Solution :
Args is deduced, its either const or not. You misunderstand how template argument deduction works here. Look at a simpler example:
template <typename T>
void foo(T& x) {
x = 42;
}
int main() {
const int x = 42;
foo(x);
}
When foo is instantiated T is deduced as const int. You can see that by means of an error for the assignment. The only reaons you cannot pass a const int to foo is the assignment, see the error:
<source>:12:7: error: assignment of read-only reference 'x'
12 | x = 42; // hence this does not compile
| ~~^~~~
If you remove that line, deduction doesnt change, ergo T is still const int. You can pass a reference to const int to foo. Same goes for std::make_format_args. Its template argument is deduced to be either const or not.