[英]C++: How can i create a function that accepts concatenated strings as parameter?
Can i design my logging-function in a way, that it accepts concatenated strings of the following form using C++? 我可以用某种方式设计我的日志记录功能,它使用C ++接受以下形式的串联字符串吗?
int i = 1;
customLoggFunction("My Integer i = " << i << ".");
. 。
customLoggFunction( [...] ){
[...]
std::cout << "Debug Message: " << myLoggMessage << std::endl << std::endl
}
Edit: 编辑:
Using std::string as the attribute to the function works for the concatenated string, but then a passed non-concatenated string like customLoggFunction("example string") produces a compile-time error saying the function is not applicable for char[]. 使用std :: string作为函数的属性适用于连接字符串,但是传递的非连接字符串(如customLoggFunction(“example string”))会产生编译时错误,表示该函数不适用于char []。 When i overload the function in the following way...
当我以下列方式重载函数时...
customLoggFunction(std::string message){...}
customLoggFunction(char message[]){...}
... the concatenated strings seize to work. ...连接的字符串抓住了工作。
I uploaded the code: http://coliru.stacked-crooked.com/a/d64dc90add3e59ed 我上传了代码: http : //coliru.stacked-crooked.com/a/d64dc90add3e59ed
It's impossible to do with the exact syntax you asked for unless you resort to macros. 除非您使用宏,否则无法使用您要求的确切语法。
But if you don't mind replacing <<
with ,
, then you can do following: 但是,如果你不介意更换
<<
有,
,那么你可以做以下操作:
#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
}
For trivial projects this is one of the few things I use a MACRO
for. 对于琐碎的项目,这是我使用
MACRO
的少数几件事之一。 You can do something like this: 你可以这样做:
#define LOG(m) do{ std::cout << timestamp() << ": " << m << '\n'; }while(0)
// ...
LOG("error: [" << errno "] " << filename << " does not exist.");
Generally MACROS
should be avoided but there is no other way to get precisely this with a standard function. 通常应该避免使用
MACROS
但没有其他方法可以通过标准功能准确地获得。 So... 所以...
Note: The empty condition do{...}while(0)
enables you to place the MACRO
in places that a MACRO
usually can't go if it contains multiple statements. 注意:空条件为
do{...}while(0)
允许您将MACRO
放置在MACRO
通常不能去的位置(如果它包含多个语句)。
You could do it by defining a new operator<<. 你可以通过定义一个新的运算符<<来做到这一点。 From vague memory, implementing functions with these three signatures will do the trick:
从模糊的内存中,使用这三个签名实现函数将起到作用:
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);
Each of them has to concatenate its arguments and return a std::string. 他们每个人都必须连接它的参数并返回一个std :: string。
Howeever, it feels wrong. 但是,感觉不对。 Goes against the grain of C++.
违背C ++的要求。 I suggest a more C++-ish solution, namely to make your logger into a class, and write operator<<() members for that class, so you can run
我建议使用更多的C ++-ish解决方案,即将您的记录器放入类中,并为该类编写运算符<<()成员,这样您就可以运行
customLog << "My Integer i = " << i << "." << "\n";
One approach is a simple utility class that uses a standard stream in a templated member function: 一种方法是使用模板化成员函数中的标准流的简单实用程序类:
class LogStream {
public:
template <class T> LogStream& operator << (const T& rhs) {
stream << rhs;
return *this;
}
private:
std::stringstream stream;
};
The stream member doing all the work is then used in the destructor, 然后在析构函数中使用完成所有工作的流成员,
~LogStream() {
std::cout << stream.str() << std::endl;
}
and you can create temporary objects for passing your arguments to be concatenated: 并且您可以创建临时对象以传递您的参数以进行连接:
LogStream() << "anything with std::ostream operator: " << 1.2345 << ' ' << std::hex << 12;
Additional state (eg a log level) can be passed to the constructor, often accompagnied by convenience functions like LogStream debug() { return LogStream(...); }
附加状态(例如,日志级别)可以传递给构造函数,通常伴随着便利函数,如LogStream
LogStream debug() { return LogStream(...); }
LogStream debug() { return LogStream(...); }
. LogStream debug() { return LogStream(...); }
。 When you reach a certain point of sophistication though, you might want to switch to a logging library of course. 但是,当您达到某种复杂程度时,您可能希望切换到日志库。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.