我可以用某种方式设计我的日志记录功能,它使用C ++接受以下形式的串联字符串吗?
int i = 1;
customLoggFunction("My Integer i = " << i << ".");
customLoggFunction( [...] ){
[...]
std::cout << "Debug Message: " << myLoggMessage << std::endl << std::endl
}
修改
使用std :: string作为函数的属性适用于连接字符串,但是传递的非连接字符串(如customLoggFunction(“example string”))会产生编译时错误,说明该函数不适用于char []。当我以下列方式重载函数时......
customLoggFunction(std::string message){...}
customLoggFunction(char message[]){...}
...连接的字符串抓住了工作。
答案 0 :(得分:7)
除非您使用宏,否则无法使用您要求的确切语法。
但如果您不介意用<<
替换,
,那么您可以执行以下操作:
#include <iostream>
#include <string>
#include <sstream>
void log_impl(const std::string &str)
{
std::cout << str;
}
template <typename ...P> void log(const P &... params)
{
std::stringstream stream;
(stream << ... << params);
// If you don't have C++17, use following instead of the above line:
// using dummy_array = int[];
// dummy_array{(void(stream << params), 0)..., 0};
log_impl(stream.str());
}
int main()
{
log("1", 2, '3'); // prints 123
}
答案 1 :(得分:4)
对于琐碎的项目,这是我使用MACRO
的少数几件事之一。你可以这样做:
#define LOG(m) do{ std::cout << timestamp() << ": " << m << '\n'; }while(0)
// ...
LOG("error: [" << errno "] " << filename << " does not exist.");
一般MACROS
应该避免但是没有其他方法可以通过标准函数准确地获得它。所以......
注意:空条件do{...}while(0)
使您可以将MACRO
放置在MACRO
通常无法进入的位置(如果它包含多个语句)。
答案 2 :(得分:2)
你可以通过定义一个新的运算符&lt;&lt;来完成它。从模糊的记忆中,使用这三个签名实现功能将起到作用:
std::string operator<<(const char * a, const std::string & b);
std::string operator<<(const std::string & a, const char * b);
std::string operator<<(const std::string & a, const std::string & b);
他们每个人都必须连接它的参数并返回一个std :: string。
但是,感觉不对。违背C ++的要求。我建议使用更多的C ++-ish解决方案,即将您的记录器变为类,并为该类编写运算符&lt;&lt;()成员,以便运行
customLog << "My Integer i = " << i << "." << "\n";
答案 3 :(得分:2)
一种方法是一个简单的实用程序类,它在模板化成员函数中使用标准流:
class LogStream {
public:
template <class T> LogStream& operator << (const T& rhs) {
stream << rhs;
return *this;
}
private:
std::stringstream stream;
};
然后在析构函数中使用完成所有工作的流成员
~LogStream() {
std::cout << stream.str() << std::endl;
}
并且您可以创建临时对象以传递您的参数以进行连接:
LogStream() << "anything with std::ostream operator: " << 1.2345 << ' ' << std::hex << 12;
可以将附加状态(例如日志级别)传递给构造函数,通常由LogStream debug() { return LogStream(...); }
等便利函数执行。但是,当您达到某种复杂程度时,您可能希望切换到日志库。