modèles, nomtype, lambda -> noms dépendants non dépendants?

Considérer:

template  boost::function f() { typedef typename Something::what type; return [](){}; } 

Dans ce code, vous avez besoin du nom de type car ‘what’ est un nom dépendant. Mais considérez ceci:

 template  boost::function f() { return []() { typedef typename Something::what type; }; } 

Bitches du compilateur: “le nom de fichier ne peut pas être utilisé en dehors d’une déclaration de modèle”

WTF?

Cela marche:

 template  boost::function f() { return []() { typedef Something::what type; }; } 

Qu’y a-t-il dans la création d’un lambda qui signifie “quoi” n’est plus un nom dépendant? Ou est-ce juste un bug?

Heh … correction. Ce dernier ne fonctionne pas. Il dit que “Quelque chose” n’existe pas. Cette version modifiée ne fonctionne pas bien et toujours de manière non intuitive, elle n’a pas besoin et n’accepte pas “typename”.

 template  struct wtf { typedef typename T::what type; }; template  boost::function f() { return []() { typedef wtf::type type; }; } 

Bien sûr, maintenant j’ai deux questions: l’original et, WTF, ne trouve-t-il pas “Quelque chose” sauf s’il est utilisé comme paramètre de modèle?

C’est une question très intéressante. D’après ma compréhension, le premier ‘WTF’ (celui avec le typename dans le corps lambda) devrait être le correct selon N3225 5.1.2 / 7:

L’ instruction composée de l’ expression lambda donne le corps de la fonction de l’opérateur d’appel de fonction, mais à des fins de recherche de nom , déterminer le type et la valeur de cette expression et transformer les expressions id faisant référence à des membres non statiques de la classe en access aux membres de la classe expressions utilisant (* this), l’ instruction composée est considérée dans le contexte de l’ expression lambda .

Comme Something est un nom dépendant dans le contexte de l’expression lambda, il doit également s’agir d’un nom dépendant dans le contexte du corps de la fonction lambda selon cette citation.

C’est parce que le lambda est en fait une classe définie par le compilateur, il ne partage pas les arguments de modèle de la fonction externe, le type lambda est défini lorsque le modèle est instancié. .