无序地图与地图

Unordered map vs map

有谁知道为什么 Dict class 无效但 Dict2 可以吗?


#include <string>
#include <unordered_map>
#include <map>
#include <variant>

class Dict
{
public:
    Dict() {}

private:
    std::unordered_map<std::string, std::variant<Dict, std::string>> data;
};

class Dict2
{
public:
    Dict2() {}

private:
    std::map<std::string, std::variant<Dict2, std::string>> data;
};

int main()
{
    Dict d;
    Dict2 d2;
    return 0;
}

我得到一个错误

‘value’ is not a member of ‘std::is_trivially_move_constructible<Dict>’.

我查阅了普通移动和复制构造的概念,据我了解,应该定义或删除移动构造函数。 我猜这是因为将 std::unordered_mapstd::variant 一起使用,编译器不知道应该如何移动对象。但是我不确定我是否理解正确。

我认为这两种情况下的行为都是未定义的。 Dict2 恰好在执行时偶然编译; “似乎有效”是未定义行为的一种可能表现形式。

[res.on.functions]/1 In certain cases (replacement functions, handler functions, operations on types used to instantiate standard library template components), the C++ standard library depends on components supplied by a C++ program. If these components do not meet their requirements, this International Standard places no requirements on the implementation.

[res.on.functions]/2 In particular, the effects are undefined in the following cases:
...
(2.5) — if an incomplete type (6.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

DictDict2 在其定义的右大括号之前是不完整的类型。 std::variant 不允许使用不完整的类型进行实例化。