web-dev-qa-db-fra.com

Référence locale à std :: cout capturée par lambda sans le demander

Ai-je perdu mon esprit? Cela a-t-il toujours été autorisé?

#include <iostream>

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

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

    write();
}

J'utilise:

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

Voir aussi sur Coliru:

( démo en direct )

J'ai toujours pensé qu'une capture vide ne capturerait rien.

En effet, MSDN dit :

Une clause de capture vide, [], indique que le corps de l'expression lambda n'accède à aucune variable dans la portée englobante.

Des recherches supplémentaires suggèrent que cela est en fait correct pour capturer const choses (que je ne savais pas non plus, mais peu importe), mais os n'est pas const (aucune référence n'est ! bien qu'il soit immuable…).

Je suis tombé sur cela en allumant -Wextra et remarquant que Clang pensait qu'un &os capture (qui est présent dans mon vrai code) n'était pas nécessaire. En le supprimant, j'ai été stupéfait de constater que la construction fonctionnait.

33

Il y a un rapport clang ouvert qui couvre le cas de capture implicite de références par des expressions lambda, cela ne se limite pas à std::cout mais à une variable de référence qui se réfère à des expressions constantes.

Pour plus de référence, le rapport de défaut de support sur le CWG est CWG-1472

MODIFIER:

Sur la base du commentaire de @ Rakete1111, j'aurais dû souligner explicitement que clang a raison d'accepter le code, qui est le résultat de l'application du défaut CWG mentionné ci-dessus. Le rapport a été rouvert en raison du lieu de diagnostic et non parce qu'ils se trompaient sur l'acceptation

23
Jans