mercredi 10 mars 2021

Class does not name a type when used as return type inside another class

I'm facing this problem when trying to create a builder design-pattern, here is the basic class:

class HtmlElement {
    friend class HtmlBuilder;

private:
    std::string name;
    std::string text;
    std::vector<HtmlElement> elements;
    const int indent_size{2};
    HtmlElement()=default;
    explicit HtmlElement(std::string, std::string);
public:
    std::string str(int indent=0)const;
};

And this is the builder class:

class HtmlBuilder {
private:
    HtmlElement root;
public:
    HtmlBuilder(const std::string &);
    HtmlBuilder &add_child(std::string, std::string);
    std::string str()const;
    operator HtmlElement()const{return root;}
};

The implementation for HtmlElement class:

HtmlElement::HtmlElement(std::string name, std::string text) : name{std::move(name)},
                                                               text{std::move(text)} {}

std::string HtmlElement::str(int indent) const {
    std::ostringstream oss{};
    std::string i{std::string(indent_size * indent, ' ')};
    oss << i << "<" << name << ">" << std::endl;
    if (!text.empty())
        oss << std::string(indent_size * (indent + 1), ' ') << text << std::endl;
    for (const auto &element:elements)oss << element.str(indent + 1);
    oss << i << "</" << name << ">" << std::endl;

    return oss.str();
}

And the implementation for HtmlBuilder class:

tmlBuilder::HtmlBuilder(const std::string &root_name) { root.name = root_name; }

HtmlBuilder &HtmlBuilder::add_child(std::string name, std::string text) {
    HtmlElement e{std::move(name), std::move(text)};
    root.elements.emplace_back(e);
    return *this;
}

std::string HtmlBuilder::str() const { return root.str(); }

Everything was compiling without any problem (and no issue with HtmlElement data member inside HtmlBuilder class) until I added this static function to the HtmlElement class:

static HtmlBuilder build(const std::string &root_name){return {root_name};}

Although HtmlBuilder.h is included, I'm having the error of "HtmlBuilder does not name a type", I tried many solutions like declaring HtmlBuilder class ahead in HtmlElement and/or declaring HtmlElement class ahead in HtmlBuilder (both headers are included in each other's classes).

Could anyone please help why it's happening when I declared a return type on class function(build inside HtmlElement) of another(HtmlBuilder) and what would be the solution?

Please note, the only way I managed to make it work was by putting all classes together in the main.cpp!!

Thanks in advance for your help!

Aucun commentaire:

Enregistrer un commentaire