在std :: map,c ++ 11中,指定密钥比较函数的函数(指针)可以作为可选参数提供。虽然摆弄了一些这样做的代码,但我从编译器得到了一些我没想到的结果。我尝试了g ++和clang ++。因为他们都同意,我猜测编译器是好的,我很困惑。
如果我声明了一个std :: map-type对象,其中指定了比较函数模板参数,但实际上没有定义比较函数,代码仍然编译并链接,我看不到任何警告。 / p>
我用-std = c ++ 11 -O0 -Wall -Wextra
编译#include <map>
typedef std::map<int, int, bool(*)(int, int)> Objs;
int main() {
#if 0
// Compiles and links as expected.
Objs objs{[](int a, int b) {
return a < b;
}};
#endif
#if 1
// FIXME The lambda definition for the key-comparing function is
// missing; why does this compile and link?
Objs objs;
#endif
objs.emplace(99997, 4210124);
(void)objs;
return 0;
}
答案 0 :(得分:1)
将单个元素插入到地图中不需要使用比较器(它是一个元素,应该比较什么?)。
添加第二个将进入UB领域。
(形式上我认为即使添加一个元素已经是UB,因为标准没有准确指定调用比较器函数的时间和次数:在单个元素的情况下不调用似乎非常合理,但只是为了调用它两次传递相同元素的乐趣我认为不违反C ++规则。)
当然注意,即使进入UB并不意味着崩溃...... UB是UB而不是发生的事情(不幸的是,包括一切)。