假设我么在制作一个html网页相关的类
string words[] = { "hello", "world" };
ostringstream oss;
oss << "<ul>";
for (auto word : words)
{
oss << " <li>" << word << "</li>";
}
oss << " </ul>";
cout << oss.str();
上述写法虽然可以实现需求,但是不够灵活,属实是trash!
我们专门给这个需求构造一个类
先看使用方式
HtmlElement list{ "ul", "" };
for (auto w : words)
list.elements.emplace_back("li", w);
cout << list.str();
定义
struct HtmlElement
{
string name, text;
vector<HtmlElement> elements;
HtmlElement() {};
HtmlElement(const string& name, const string& text)
: name(name), text(text)
{}
string str(int indent = 0) const
{
ostringstream oss;
oss << "<" << name << "> ";
oss << text;
for (auto word : elements)
{
oss << word.str();
}
oss << " </" << name << ">";
return oss.str();
}
};
稍微好一点,我们更进一步,专门给这个类加一个构造器
struct HtmlBuilder
{
HtmlElement root;
HtmlBuilder(string root_name) { root.name = root_name; }
void add_child(string child_name, string child_text)
{
root.elements.emplace_back(child_name, child_text);
}
string str() { return root.str(); }
operator HtmlElement() const { return root; }
};
使用方式
HtmlBuilder builder{ "ul" };
builder.add_child("li", "hello");
builder.add_child("li", "world");
cout << builder.str() << std::endl;
我们还可以利用add_child 的返回值,让构造器支持流式操作
HtmlBuilder& add_child(string child_name, string child_text)
{
root.elements.emplace_back(child_name, child_text);
return *this;
}
HtmlBuilder builder{ "ul" };
builder.add_child("li", "hello")
.add_child("li", "world");
cout << builder.str() << std::endl;