C++ 将不同的类型连接成函数的字符串

c++ concatenate different types into a string for function

本文关键字:函数 字符串 连接 类型 C++      更新时间:2023-10-16

我的应用程序的不同部分调用记录器函数来记录详细信息。

记录器类

std::string filename = "blahblah"; // variable to store the location of the properties file 
log4cpp::PropertyConfigurator::configure(filename);
void Logger::logging(const std::string& msg)
{
Log4cpp::Category& myLogger = log4cpp::Category::getRoot();
myLogger.log(log4cpp::Priority::INFO, msg);//only takes in string as input
}

调用类

Logger logMe;
int a = 5;
double b = 6;
logMe.logging("log this msg" + a + "," + b);

我意识到以上会给我错误,因为ab是不同类型的。解决它的一种方法是使用std::to_string

logMe.logging("log this msg" + std::to_string(a) + "," + std::to_string(b));

但是,我对日志记录功能有数百个调用,并且编辑对std::to_string的每个调用都会很耗时。有没有更简单的方法可以做到这一点?

哦,澄清一下,代码之前的工作方式与之前的方式一样,是通过定义 #define 函数。

#Define logging(FLAG, X)
do {
...
clog << x; 
}while(0)
logging(LogFlag::Warning, "log this msg" << a << "," << b << endl);

但是我现在正在重写部分代码以符合静态测试。

提前谢谢。

您可以使用std::stringstream添加logging重载,该重载采用参数包并将其联接到字符串

中在 c++17 中,我们可以使用折叠表达式,例如

template <typename Args ...>
void Logger::logging(Args ... args)
{
std::stringstream ss;
(ss << ... << args); 
Log4cpp::Category& myLogger = log4cpp::Category::getRoot();
myLogger.log(log4cpp::Priority::INFO, ss.str());
}

在 c++11 或 14 中,我们必须稍微棘手一些

template <typename ... Args >
void Logger::logging(Args ... args)
{
std::stringstream ss;
std::initializer_list<int> unused{ (ss << args, 0)... };
Log4cpp::Category& myLogger = log4cpp::Category::getRoot();
myLogger.log(log4cpp::Priority::INFO, ss.str());
}

然后你调用任何一个,例如

logMe.logging("log this msg", a, ",", b);

我建议在类中添加一个operator<<()

class Logger
{
public:
Logger &operator<<(const std::string &s)
{
logging(s)
return *this;
};
Logger &operator<<(const char *s)
{
return operator<<(std::string(s));
}

template <class T>
Logger &operator<<(const T &v)
{
std::ostringstream s;
s << v;
return operator<<(logging(ss.str()));
};
// other stuff you have in your class, including the logging() function
};
//  to use
logMe << "log this msg" << a << b;

与您描述的使用它的语法不完全相同,但它更普遍地工作。

使用stringstream相当容易。然后,您可以使用str()将其转换为std::string

#include <sstream>
...
int a = 5;
double b = 6;
std::stringstream ss;
ss << "log this msg" << a << b;
std::cout << ss.str() << std::endl;
logMe.logging(ss.str());