首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >类型转换,‘初始化’:无法从'HtmlBuilder *‘转换为'HtmlElement’

类型转换,‘初始化’:无法从'HtmlBuilder *‘转换为'HtmlElement’
EN

Stack Overflow用户
提问于 2018-07-06 04:45:23
回答 1查看 32关注 0票数 1

我正在努力学习一个教程,但我也很难为unique_ptr实现流畅的构建器。尽管我知道这是一个类型转换的问题,并且在检查了文档之后,我还是没能找到一个合适的修复方法。

代码语言:javascript
复制
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <memory>

using namespace std;

class HtmlBuilder;


struct HtmlElement
{
    string name;
    string text;

    vector<HtmlElement> elements;
    const size_t indent_size = 2;


    HtmlElement() {}



    HtmlElement(const string& name, const string& text) : name{ name }, text{ text }
    {

    }

    string str(int indent = 0) const // it is a const because it doesn't change the inner elements of htmlelement
    {
        ostringstream oss;
        string i(indent_size * indent, ' '); // repeating a character as many times as required. 

        oss << i << "<" << name << ">" << endl;


        if (text.size() > 0)
            oss << string(indent_size * (indent + 1), ' ') << text << endl;

        // recursive call
        for (const auto& e : elements)
            oss << e.str(indent + 1);

        oss << i << "</" << name << ">" << endl;
        return oss.str();
    }




    static HtmlBuilder build(string root_name);
    static unique_ptr<HtmlBuilder> create(string root_name);

};



struct HtmlBuilder
{

    HtmlBuilder(string root_name)
    {
        root.name = root_name;
    }




    HtmlElement root; // we can not do anything without root



    HtmlBuilder& add_child(string child_name, string child_text)
    {
        HtmlElement e{ child_name, child_text };


        root.elements.emplace_back(e);


        // it is a reference
        return *this;


    }


    HtmlBuilder* add_child2(string child_name, string child_text)
    {
        HtmlElement e{ child_name, child_text };


        // emplace_back will return a reference to element that was just created in the vector where as push_back does not return anything, so you could preform some chaining if you wanted
        root.elements.emplace_back(e);


        // it is a pointer
        return this;
    }

    string str() const {
        return root.str();
    }


    // let's you convert the builder to htmlelement.
    // automatic conversion.
    // it wil be converted only after the chaining has finished.
    operator HtmlElement() { return root; }





    /*B& operator= (const A& x) { return *this; }*/
    //operator unique_ptr<HtmlElement>() { 


    //  return root; 
    //}

};


// it had to be pasted here after definition of HtmlBuilder
HtmlBuilder HtmlElement::build(string root_name)
{

    // it will get automatically converted to a html element due to 
    // automatic conversion.
    return HtmlBuilder{ root_name };
}


unique_ptr<HtmlBuilder> HtmlElement::create(string root_name) {
    return make_unique<HtmlBuilder>(root_name);
}


// Basically we want to create builder from HtmlElement itself
// and be able to add childs as many as we want and at the end
// it will still return an HtmlElement due to automatic conversion
// in this way we hide builder completely

int main()
{

    HtmlBuilder builder{ "ul" };

    builder.add_child("li", "hello")
        .add_child("li", "world");

    //HtmlElement e = builder;


    // important: automatic conversion occurs only at the end, if the object itself is returned.
    HtmlElement e = HtmlElement::build("ul").add_child("li", "test").add_child("li", "test2");
    HtmlElement ee = HtmlElement::create("ul")->add_child2("li", "test")->add_child2("li", "test2");


    cout << e.str() << endl;





    getchar();
    return 0;
}

问题出在尝试使用下面这行代码:

代码语言:javascript
复制
HtmlElement::create("ul")->add_child2("li", "test")->add_child2("li", "test2");

它抛出错误,如上所述。它说不能从'HtmlBuilder *‘转换成'HtmlElement’。尝试了几种解决方案,但我是C++的初学者,到目前为止还没有成功修复它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-06 05:18:41

你有一个要从HtmlBuilder转换成HtmlElement的operator(),但没有从HtmBuilder*转换成HtmlElement。这就是build()行和create()行之间的区别。

因此,必须取消对create()->add_child2()行返回的指针的引用。

尝尝这个

代码语言:javascript
复制
HtmlElement ee = *(HtmlElement::create("ul")->add_child2("li", "test")->add_child2("li", "test2"));

Wandbox上运行

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51199627

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档