为什么 std::map 代码在未为其数据类型定义运算符 < 时编译?

Why does std::map code compile when operator < is not defined for its data type?

我了解到,将用户定义的类型传递给 std::map(以及许多其他 STL 数据结构)需要定义 operator <

然而,这是否意味着编译器能够在编译时验证 std::map 的声明是否正确?下面的代码声明了一个 std::map 和一个没有 < 运算符的用户定义数据类型,仍然可以编译。有人可以告诉我为什么这是真的吗?

#include <iostream>
#include <fstream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

struct Test{
    int a;
    string b;
};

int main()
{
    map <Test, int> M; // shouldn't this line cause a compilation error, as operator < is not defined                  
                       // for class Test?

    return 0;
}

在 C++ 中(脚注) 模板对其类型参数没有静态约束(与 C# 的 where 约束不同)。相反,C++ 模板参数参数的 正确性 只有在编译器实例化每个模板成员时才能确定(compile-time type instantiation,而不是运行时对象实例化)。您的代码仅使用 map 的无参数构造函数,不使用 key_type 的重载 < 运算符。

如果您有 npm JavaScript 生态系统的经验,请将其视为 极端的 tree-shaking :不使用的库函数是'编译,如果它们未编译,则它们不会出现编译器错误。 C++ 语言的 零开销原则 也被称为 "You don't pay for what you don't use" (尽管不要将其与“零成本抽象”这是另外一回事)。

1: C++20 has added template parameter constraints, but I imagine we won't see that in STL types for long while as it would be a major breaking change : https://en.cppreference.com/w/cpp/language/constraints