为什么以下不编译?

Why does the following not compile?

给定以下代码,

#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;
}

当方法 get_content() 是虚函数时,它不会编译,否则会编译。 这是为什么?

如果成员函数不是 virtual,那么您的 class 是一个 聚合 class。 (有关制作 class 聚合的要求,请参阅 here。)

聚合class可以聚合初始化,这意味着它可以用花括号初始化器列表初始化,例如{"dddd", ""},聚合初始化将初始化class 的每个 non-static 数据成员由列表中的连续条目组成,无需调用 class.

的构造函数

如果添加虚成员函数class不再是聚合class,因为聚合classes可能根本没有虚成员函数,因此聚合初始化不可能。

那么初始化 class 的唯一方法是通过构造函数,但是 class 唯一的构造函数是隐式默认构造函数,它不接受任何参数,而隐式复制和移动构造函数,它只接受一个参数。

您正在尝试使用两个参数 ({"dddd", ""}) 进行构造,因此它将失败。

如果你想要虚成员函数,那么你需要提供一个合适的构造函数,例如:

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_) {
    } 
};

没有虚函数,sstruct是一个集合。在这种情况下,{"dddd", ""} 有效,因为它是聚合初始化。

跟虚函数sstruct不是聚合。在这种情况下,{"dddd", ""} 不起作用,因为它不能被聚合初始化,并且您没有定义接受两个参数的构造函数,也没有定义接受 std::initializer_list.[=15= 的构造函数]

代码中有几处错误。我做了一些修改,以使其正常工作。下面的代码是正确的-

#include <iostream>
#include <unordered_map>
using namespace std;

struct sstruct {
    string content;
    string view_name;
    
    string get_content()
    {
        return "";
    }
};

int main()
{
    unordered_map<string, sstruct> name{
        {"pippo", {"dddd", ""}}
    };
    
    cout<<name["pippo"].content<<endl;
    return 0;
}