使用未定义的比较函数定义std :: map编译和链接,这让我感到惊讶

时间:2015-01-05 21:25:08

标签: c++ c++11

在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;
}

1 个答案:

答案 0 :(得分:1)

将单个元素插入到地图中不需要使用比较器(它是一个元素,应该比较什么?)。

添加第二个将进入UB领域。

(形式上我认为即使添加一个元素已经是UB,因为标准没有准确指定调用比较器函数的时间和次数:在单个元素的情况下不调用似乎非常合理,但只是为了调用它两次传递相同元素的乐趣我认为不违反C ++规则。)

当然注意,即使进入UB并不意味着崩溃...... UB是UB而不是发生的事情(不幸的是,包括一切)。