C'est la question centrale 728, qui a été déposée avant le générique lambdas agissait d'une chose.
Vous avez mentionné générique lambdas et qu'ils étaient identiques pour les classes locales avec des membres correspondants template operator()
. Cependant, ils ne le sont pas vraiment, et les différences sont liées à la mise en œuvre de ses caractéristiques. Envisager
template <typename T>
class X {
template <typename>
void foo() {
T t;
}
};
Et
template <typename T>
auto bar() {
return [] (auto) {T t;};
};
L'instanciation de ces modèles avec des <void>
sera parfait dans le premier cas, mais mal-formé dans la deuxième. Pourquoi amende dans le premier cas? foo
n'ont pas besoin d'être instantiatable pour chaque T
, mais seulement l'un d'eux (ce serait [temp.res]/(8.1)).
Pourquoi mal formé dans le second cas? Le générique lambda corps est instancié - partiellement - à l'aide du gabarit fourni des arguments. Et la raison de cette instanciation partielle est le fait que...
...le lexique des étendues utilisées lors du traitement d'une définition de fonction sont fondamentalement transitoire, ce qui signifie que le report de l'instanciation d'une partie d'un modèle de fonction définition est difficile à soutenir.
(Richard Smith), Nous devons instancier assez de la local de "modèle" pour les rendre indépendants du contexte local (qui comprend les paramètres du modèle de la fonction englobante modèle).
C'est également liée à la justification de
[expr.prim.lambda]/13, qui exige qu'une entité est implicitement capturé par un lambda si il...
les noms de l'entité dans une potentiellement-de l'expression évaluée ([base.def.odr]) où la enfermant pleine expression dépend d'un générique de paramètre lambda déclarée dans le large spectre de la lambda-expression.
C'est, si j'ai un lambda comme [=] (auto x) {return (typename decltype(x)::type)a;}
où a
est quelque bloc-portée variable à partir d'une fonction englobante, indépendamment de si x
s'membre typedef est pour void
ou pas, le casting sera la cause d'une capture d' a
, parce que nous devons nous décider sur ce, sans attendre un appel de la lambda. Pour une discussion de ce problème, voir l' origine de la proposition de génériques lambdas.
La ligne de fond est que complètement le report de l'instanciation d'un membre de modèle n'est pas compatible avec le modèle utilisé par (au moins un) majeur de la mise en œuvre(s), et étant donné que ceux sont les attendus de la sémantique, la fonctionnalité n'a pas été introduit.
Est que la motivation première de cette contrainte? Il a été introduit quelque part entre janvier et Mai 1994, avec pas de papier couvrant, donc nous ne pouvons avoir une idée approximative de l'état de l'notions de ce documents'justification de pourquoi les classes ne sont pas des arguments template:
Modèles de classe et les classes générées à partir du modèle sont de portée mondiale
les entités et ne peut pas se référer à une portée locale entités.
Peut-être à l'époque, on voulait l'EMBRASSER.