Suppose I have a log function like this:
void myLog(const char* msg);
The above assumption can't be changed.
then how can I call it easily in c ; usually I write the code like this:
stringstream ss;
ss << "name : " << name << " age " << age;
mylog(ss.str().c_str());
can I can reduce the 3 lines to 1 line in c somehow?
thanks!
CodePudding user response:
If you use C 20, you should be able to use std::format
.
So your code would look like this:
myLog(std::format("name: {} age: {}", name, age).c_str());
CodePudding user response:
Yes, you can stream into a temporary std::stringstream
myLog((std::stringstream{} << "name : " << name << " age " << age).str().c_str());
CodePudding user response:
Yes you can, if you are willing to put some code in a seperate header file :
#include <string>
#include <sstream>
#include <iostream>
#include <type_traits>
// given
void myLog(const char* msg)
{
std::cout << msg << "\n";
}
// this goes into a header file
namespace details
{
// this function is called with a variable number of arguments
// by splitting the template into a value_t and a variadic part
// we basically pick out only the first argument
template<typename value_t, typename... args_t>
void stream_to_os(std::stringstream& os, const value_t& value, args_t&&... args)
{
// pick out the first argument and stream it to the stringstream
os << value;
// then check (at compile time!) if there are any more arguments to stream
// if so recurse into this function. Rince and repeat.
if constexpr (sizeof...(args_t) > 0)
{
stream_to_os(os, std::forward<args_t>(args)...);
}
}
}
// make use of the fact that you can overload existing functions
// if a const char* is passed then still the original log function will be selected
// otherwise this template function is considered.
template<typename... args_t>
void myLog(args_t&&... args)
{
// create the stream once
std::stringstream os;
// then stream the variadic arguments to the stringstream
details::stream_to_os(os, std::forward<args_t>(args)...);
// and now call the original myLog function
myLog(os.str().c_str());
}
//--------------------------------------------------------
// add an include to the header file with the stuff above
// and you can log like this:
int main()
{
const char* name{ "John Doe" };
unsigned int age{ 42u };
myLog("name = ", name, ", age = ", age);
return 0;
}
CodePudding user response:
You can use std::to_string
and addition operator instead of the string stream, but that limits you to conversion of built in types (or other types with this function implemented for)
mylog(("name:" name " age:" std::to_string(age)).c_str());