c++ - 当未为其数据类型定义运算符 < 时,为什么 std::map 代码会编译?

标签 c++ struct stdmap

我了解到将用户定义类型传递给 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 生态系统,将其视为极端的树摇动:不使用的库函数不会被编译,如果它们没有被编译,那么它们就不会受到编译器错误的影响。 C++ 语言的这种零开销原则也称为 "You don't pay for what you don't use" (不过不要将其与“零成本抽象”混淆,后者是其他东西)。

1 :C++20 添加了模板参数约束,但我想我们不会在 STL 类型中看到很长一段时间,因为这将是一个重大的突破性变化:https://en.cppreference.com/w/cpp/language/constraints

关于c++ - 当未为其数据类型定义运算符 < 时,为什么 std::map 代码会编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65057010/

相关文章:

c++ - 带映射迭代器的 For 循环退出条件

c++03: std::map 中内置类型的默认构造函数

c++ - 将 boost::bimap 转换为 std::map

c++ - Makefile: multiple definition and undefined reference 错误

c++ - 在变体中从原始类型到用户定义类型的隐式转换

c - 使用结构指针和数组编写以下函数的代码

ios - 访问数组中对象的属性 - Swift 3.0

c++ - 编译器在编译时如何检测数字溢出?

c++ - 将 unicode 参数传递给 QApplication

swift - STRUCT 数组到用户默认值