Локальная ссылка на std :: cout, захваченная лямбдой без запроса
Я сошел с ума? Это всегда было разрешено?
#include <iostream>
int main()
{
auto& os = std::cout;
auto write = []()
{
os << "what\n";
};
write();
}
Я использую:
Apple LLVM версия 10.0.0 (clang-1000.10.44.4)
Цель: x86_64-apple-darwin17.7.0
Хотя и смотри по колиру
Я всегда думал, что пустой захват ничего не захватит.
Действительно, MSDN говорит:
Пустое предложение захвата, [], указывает, что тело лямбда-выражения не обращается ни к каким переменным во внешней области видимости.
Дальнейшие исследования показывают, что на самом деле это нормально для захвата const
(что я тоже не знал, но что угодно), но os
не является const
(нет ссылки! Хотя она неизменна…).
Я столкнулся с этим при включении -Wextra
и заметил, что Clang считает, что захват &os
(который присутствует в моем реальном коде) не нужен. Удаляя его, я был поражен, обнаружив, что сборка работает.
Ответы
Ответ 1
Есть открытый отчет clang, который охватывает случай неявного захвата ссылок лямбда-выражениями, это не ограничивается std::cout
а ссылочной переменной, которая, как было обнаружено, ссылается на константные выражения.
Для получения дополнительной информации отчет о дефекте подложки на CWG - CWG-1472.
РЕДАКТИРОВАТЬ:
Основываясь на комментарии @Rakete1111, я должен был четко указать, что clang прав в принятии кода, который является результатом применения дефекта CWG, упомянутого выше. Отчет был вновь открыт из-за местоположения диагноза, а не потому, что они ошиблись в принятии