One of the most exciting new functions in C++20 is std::format
. I have never liked the ways that strings are formatted in C++ and have been guilty many times of using sprintf
and such.
Since std::format
is not implemented by any of the major compilers at this time, I thought I would try out my own very basic implementation and this is what I have come up with:
#include <string_view>
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>
void format_helper(std::ostringstream& oss, std::string_view str) // base function
{
oss << str;
}
template<typename T, typename... Targs>
void format_helper(std::ostringstream& oss, std::string_view str, T value, Targs... args)
{
std::size_t openBracket = str.find_first_of('{');
if (openBracket != std::string::npos)
{
std::size_t closeBracket = str.find_first_of('}', openBracket + 1);
if (closeBracket == std::string::npos)
throw std::runtime_error("missing closing bracket.");
oss << str.substr(0, openBracket);
oss << value;
format_helper(oss, str.substr(closeBracket + 1), args...);
return;
}
oss << str;
}
std::string format(std::string_view str)
{
return std::string(str);
}
template<typename T, typename... Targs>
std::string format(std::string_view str, T value, Targs...args)
{
std::ostringstream oss;
format_helper(oss, str, value, args...);
return oss.str();
}
int main()
{
int a = 5;
double b = 3.14;
std::string c("hello");
// correct number of arguments
std::cout << format("a = {}, b = {}, c = {}", a, b, c) << "\n";
// too few arguments
std::cout << format("a = {}, b = {}, c = {}", a, b) << "\n";
// too many arguments
std::cout << format("a = {}, b = {}, c = {}", a, b, c, 12.4) << "\n";
}
\n
in the format string :) \$\endgroup\$