我想为 ostream 实现一个自定义操纵器,以对插入流中的下一个项目进行一些操作。例如,假设我有一个自定义操纵器quote:
std::ostringstream os;
std::string name("Joe");
os << "SELECT * FROM customers WHERE name = " << quote << name;
机械手quote将引用name生产:
SELECT * FROM customers WHERE name = 'Joe'
我该如何实现这一目标?
谢谢。
将操纵器添加到 C++ 流中特别困难,因为人们无法控制操纵器的使用方式。人们可以将新的语言环境注入到流中,该流安装了一个方面来控制数字的打印方式,但不控制字符串的输出方式。然后问题仍然是如何将引用状态安全地存储到流中。
使用定义在中的运算符输出字符串std
命名空间。如果您想更改这些打印方式,同时保持操纵器的外观,您可以创建一个代理类:
namespace quoting {
struct quoting_proxy {
explicit quoting_proxy(std::ostream & os):os(os){}
template<typename Rhs>
friend std::ostream & operator<<(quoting_proxy const& q,
Rhs const& rhs) {
return q.os << rhs;
}
friend std::ostream & operator<<(quoting_proxy const& q,
std::string const& rhs) {
return q.os << "'" << rhs << "'";
}
friend std::ostream & operator<<(quoting_proxy const& q,
char const* rhs) {
return q.os << "'" << rhs << "'";
}
private:
std::ostream & os;
};
struct quoting_creator { } quote;
quoting_proxy operator<<(std::ostream & os, quoting_creator) {
return quoting_proxy(os);
}
}
int main() {
std::cout << quoting::quote << "hello" << std::endl;
}
哪个适合用于ostream
。如果您想概括,您也可以将其作为模板并接受basic_stream
而不是普通的string
。在某些情况下,它与标准操纵器有不同的行为。因为它通过返回代理对象来工作,所以它不适用于类似的情况
std::cout << quoting::quote;
std::cout << "hello";
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)