【问题标题】:Why is this lambda streamable?为什么这个 lambda 可以流式传输?
【发布时间】:2017-07-10 02:31:42
【问题描述】:

令我惊讶的是,下面的代码打印出1

std::cout << [](const char* arg){ return arg[0]=='s'; } << std::endl;

有人可以解释一下吗?

【问题讨论】:

  • 我认为它正在转换为bool
  • 有趣的部分是std::cin &gt;&gt; [](const char* arg){ return arg[0]=='s'; } 是否有效。 ;)

标签: c++ c++11 lambda cout


【解决方案1】:

它正在转换为函数指针,然后通过它转换为布尔值:

void foo ();
std::cout << &foo << std::endl;

打印同样的东西,同样的警告;我碰巧将 gcc 设置为 17 标准进行编译,我看到了:

main.cpp:6:56: warning: the address of 'static constexpr bool main()::<lambda(const char*)>::_FUN(const char*)' will never be NULL [-Waddress]
  std::cout << [](const char* arg){ return arg[0]=='s'; } << std::endl;

使用上面的代码,您会看到相同的警告。

补充一点我的答案:void* 存在流过载。但是,与指向数据的指针不同,函数指针不能隐式转换为void*。函数指针唯一的隐式转换是布尔值,当然还有布尔的流操作,这样就选择了重载,发生了隐式转换。请参阅:How to print function pointers with cout?

【讨论】:

  • @M.M lambda 首先转换为函数指针,然后通过该指针转换为布尔值。我实际上并不知道函数指针在流式传输时会转换为布尔值,老实说这很奇怪。
  • @NirFriedman 这完全合理。根据标准当前工作草案的 8.1.5.1(6),无捕获 lambda 具有指向函数指针的转换运算符,并且根据 7.14,指针可以隐式转换为 bool。关键点是第二次转换是隐式发生的,这就是允许两次转换的原因。如果这是第二次用户定义的转换,则不会发生。
  • @HenriMenke 由于 lambdas 函数并不是真正的“用户定义”,我有点惊讶 lambda -> 函数指针被视为用户定义的转换。但是,是的,我关于函数指针作为布尔值流式传输的评论只是说乍一看似乎有点令人惊讶(而且不是很有用)。一旦你想得更多,它就有意义了,这只是几个合理的事情会议中出现的令人惊讶的行为的一个例子。
猜你喜欢
  • 1970-01-01
  • 2022-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多