为什么 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
我了解到,将用户定义的类型传递给 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