Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why does the following not compile?

Given the following code,

#include <iostream>
#include <string>
#include <string_view>
#include <unordered_map>

struct sstruct {
    std::string content;
    std::string_view name;

    virtual std::string get_content() {
        return "";
    }
};

int main() {

    std::unordered_map<std::string, sstruct> map{
            {
                    "pippo", {"dddd", ""}
            }
    };

    std::cout << map["pippo"].content << std::endl;
}

when the method get_content() is virtual it does not compile, otherwise, it does.
Why is that?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

If the member function is not virtual, then your class is an aggregate class. (For the requirements making a class aggregate, see here.)

An aggregate class can be aggregate initialized, which means it can be initialized with a braced initializer list such as {"dddd", ""} and aggregate initialization will initialize each non-static data member of the class by successive entries in the list, without calling a constructor of the class.

If you add a virtual member function the class is no longer an aggregate class, because aggregate classes may not have virtual member functions at all, and therefore aggregate initialization is not possible.

Then the only way to initialize the class is via a constructor, but the only constructor your class has are the implicit default constructor, which doesn’t take any arguments, and the implicit copy and move constructors, which take exactly one argument.

You are trying to construct with two arguments ({"dddd", ""}) and so it will fail.

if you want the virtual member function, then you need to provide an appropriate constructor, e.g.:

struct sstruct {
    std::string content;
    std::string_view name;

    virtual std::string get_content() {
        return "";
    }

    sstruct(std::string content_, std::string_view name_)
        : content(std::move(content_)), name(name_) {
    } 
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading