Локальная ссылка на 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, упомянутого выше. Отчет был вновь открыт из-за местоположения диагноза, а не потому, что они ошиблись в принятии