用户定义方法中的运算符 <<
Operator << in a user defined method
我正在尝试编写一种方法,该方法将使用 >>
运算符作为类似于 std::cin
的参数来获取参数,但我不知道如何实现。是否可以创建这种方法,将此流作为参数,正确转换(例如将所有整数转换为字符串等),然后保存到 std::string 变量?
这是我想要如何 运行 函数的示例:
int i = 0;
myMethod << "some text" << i << "moar text";
在该方法中,我想获取这些参数并存储在一个字符串中。
编辑
我将尝试准确解释此应用程序的内容:我正在尝试制作一个 Clogger 单例 class,它将用于将日志保存到文件中。通过这种构造,我可以从代码中的任何位置调用 *CLogger::instance() << "log stuff";
,这没问题。多亏了这个主题的答案,我才来到这里。问题是每个 operator<<
我使用,然后将调用该对象。所以如果我做 *CLogger::instance() << "log stuff" << " more stuff" << " even more";` 这个方法(?)将被调用 3 次:
template<typename T>
CLogger& operator<<(const T& t)
{
...
return *this;
}
这对我不利,因为我打算在每个日志行前后添加一些文本。例如,我总是想在之前和之后添加时间 std::endl
。按照我给出的例子而不是得到:
[00:00] log stuff more stuff even more
我会得到:
[00:00] log stuff
[00:00] more stuff
[00:00] even more
所以我尝试通过改变这样的方法来消除这种行为:
template<typename T>
CLogger& operator<<(const T& t)
{
ostringstream stream;
stream << t;
m_catString += stream.str();
if (stream.str() == "\n")
{
push_back(m_catString);
m_catString.clear();
}
return *this;
}
这样,如果我在末尾添加 "\n"
,程序就会知道何时推送新的日志行。几乎没问题,因为我打赌我会忘记添加它。还有什么更巧妙的方法吗?
我知道的唯一方法是创建 class class Method
然后重载 operator<<
、operators overloading
template<class T>
Method &operator<<(const T &x)
{
// Do whatever you like
return *this;
}
然后你可以像这样使用它:
Method myMethod;
myMethod << ... ;
你可以看看 this question 关于创建一个 cout
-like class
std::cin 和 std::cout 不是函数
编辑
class CLogger
{
...
template<typename T>
CLogger& operator<<(const T& t)
{
push_back(std::to_string(t));
return *this;
}
};
您不必创建 class Pusher,只需在您的第一个 class 中重载运算符,现在您可以将它用于您的对象:
myCLogger << t; // this would call the function push back
您不能使用 <<
将参数传递给方法,您需要一个对象。
像这样:
struct A
{
template<typename T>
A& operator<<(const T& t)
{
std::ostringstream stream;
stream << t;
data += stream.str();
return *this;
}
std::string data;
};
// ...
A a;
a << "Hello " << 34 << " World";
std::cout << a.data;
关于您的更新:
最明显的事情是在 CLogger
中实现运算符而不是 Pusher
class;那会让你写 *CLogger::instance() << "sample text" << 10;
如果您出于某种原因不能这样做(您正在零碎地提供信息,所以很难分辨),您可以声明 Pusher
为朋友并使用与其他地方相同的方法:
struct Pusher
{
template<typename T>
Pusher& operator<<(const T& t)
{
std::ostringstream stream;
stream << t;
CLogger::instance()->push_back(stream.str());
return *this;
}
};
我正在尝试编写一种方法,该方法将使用 >>
运算符作为类似于 std::cin
的参数来获取参数,但我不知道如何实现。是否可以创建这种方法,将此流作为参数,正确转换(例如将所有整数转换为字符串等),然后保存到 std::string 变量?
这是我想要如何 运行 函数的示例:
int i = 0;
myMethod << "some text" << i << "moar text";
在该方法中,我想获取这些参数并存储在一个字符串中。
编辑
我将尝试准确解释此应用程序的内容:我正在尝试制作一个 Clogger 单例 class,它将用于将日志保存到文件中。通过这种构造,我可以从代码中的任何位置调用 *CLogger::instance() << "log stuff";
,这没问题。多亏了这个主题的答案,我才来到这里。问题是每个 operator<<
我使用,然后将调用该对象。所以如果我做 *CLogger::instance() << "log stuff" << " more stuff" << " even more";` 这个方法(?)将被调用 3 次:
template<typename T>
CLogger& operator<<(const T& t)
{
...
return *this;
}
这对我不利,因为我打算在每个日志行前后添加一些文本。例如,我总是想在之前和之后添加时间 std::endl
。按照我给出的例子而不是得到:
[00:00] log stuff more stuff even more
我会得到:
[00:00] log stuff
[00:00] more stuff
[00:00] even more
所以我尝试通过改变这样的方法来消除这种行为:
template<typename T>
CLogger& operator<<(const T& t)
{
ostringstream stream;
stream << t;
m_catString += stream.str();
if (stream.str() == "\n")
{
push_back(m_catString);
m_catString.clear();
}
return *this;
}
这样,如果我在末尾添加 "\n"
,程序就会知道何时推送新的日志行。几乎没问题,因为我打赌我会忘记添加它。还有什么更巧妙的方法吗?
我知道的唯一方法是创建 class class Method
然后重载 operator<<
、operators overloading
template<class T>
Method &operator<<(const T &x)
{
// Do whatever you like
return *this;
}
然后你可以像这样使用它:
Method myMethod;
myMethod << ... ;
你可以看看 this question 关于创建一个 cout
-like class
std::cin 和 std::cout 不是函数
编辑
class CLogger
{
...
template<typename T>
CLogger& operator<<(const T& t)
{
push_back(std::to_string(t));
return *this;
}
};
您不必创建 class Pusher,只需在您的第一个 class 中重载运算符,现在您可以将它用于您的对象:
myCLogger << t; // this would call the function push back
您不能使用 <<
将参数传递给方法,您需要一个对象。
像这样:
struct A
{
template<typename T>
A& operator<<(const T& t)
{
std::ostringstream stream;
stream << t;
data += stream.str();
return *this;
}
std::string data;
};
// ...
A a;
a << "Hello " << 34 << " World";
std::cout << a.data;
关于您的更新:
最明显的事情是在 CLogger
中实现运算符而不是 Pusher
class;那会让你写 *CLogger::instance() << "sample text" << 10;
如果您出于某种原因不能这样做(您正在零碎地提供信息,所以很难分辨),您可以声明 Pusher
为朋友并使用与其他地方相同的方法:
struct Pusher
{
template<typename T>
Pusher& operator<<(const T& t)
{
std::ostringstream stream;
stream << t;
CLogger::instance()->push_back(stream.str());
return *this;
}
};