Local reference to std::cout captured by lambda wi

2019-04-17 20:15发布

问题:

Have I lost my mind? Was this always permitted?

#include <iostream>

int main()
{
    auto& os = std::cout;

    auto write = []()
    {
        os << "what\n";
    };

    write();
}

I'm using:

Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin17.7.0

Though also see on Coliru:

(live demo)

I always thought an empty capture would not capture anything.

Indeed, MSDN says:

An empty capture clause, [ ], indicates that the body of the lambda expression accesses no variables in the enclosing scope.

Further research suggests that this is in fact okay for capturing const things (which I also didn't know, but whatever), but os is not const (no reference is! though it is immutable…).

I came across this when turning on -Wextra and noticing that Clang thought a &os capture (which is present in my real code) was unnecessary. Removing it I was staggered to find the build worked.

回答1:

There's an open clang report that cover the case of implicit capture of references by lambda expressions, this is not limited to std::cout but to references variable that are found to refer to constant expressions.

For more reference, the backing defect report on the CWG is CWG-1472

EDIT:

Based on @Rakete1111 comment, I should have pointed out explicitly that clang is right in accepting the code, which is the result of applying the CWG defect mentioned above. The report was reopened because of diagnosis location not because they were wrong about the acceptance