La déduction de paramètre de modèle peut-elle être utilisée dans les membres de données de classe?

C ++ 17 introduit la déduction d’argument de modèle .

Avec gcc-7.2, je peux l’utiliser facilement dans une fonction:

int test() { std::pair d(0, 0.0); } 

Je m’attendais à ce que cette même syntaxe fonctionne dans la classe des membres de données non statiques, comme:

 class Test { std::pair d_{0, 0.0}; }; 

mais cela provoque l’ error: invalid use of template-name ... without an argument list gcc error: invalid use of template-name ... without an argument list , avec --std=c++17 passé.

J’ai essayé quelques autres combinaisons, mais aucune ne semble fonctionner.

S’agit-il du comportement souhaité par le standard ou s’agit-il d’un support incomplet du compilateur? Je ne trouve aucune référence explicite aux membres de données de classe dans la norme.

Mon cas d’utilisation est bien sûr beaucoup plus complexe, cette syntaxe serait extrêmement pratique (pensez aux fonctions passées et stockées).

S’agit-il du comportement souhaité par le standard ou s’agit-il d’un support incomplet du compilateur?

Oui, c’est le comportement prévu. [dcl.type.class.deduct] lit:

Si un espace réservé pour un type de classe déduit apparaît en tant que spécificateur de déclaration dans la déclaration de spécification de déclaration d’une initialisation ([dcl.init]) d’ une variable , […]

Un espace réservé pour un type de classe déduit peut également être utilisé dans le type-specifier-seq dans le nouveau-type-id ou le type-id d’une nouvelle expression , ou en tant que spécificateur de type simple dans une conversion de type explicite notation). Un espace réservé pour un type de classe déduit ne doit pas apparaître dans un autre contexte .

Un membre de données non statique n’est pas une variable et nous ne sums dans aucune des autres situations.

Notez que le même principe s’applique aux membres de données non statiques qui tentent d’être déclarés avec auto :

 struct X { auto y = 0; // error }; 

L’initialisateur de membre par défaut est juste cela – un initialiseur par défaut. Que se passe-t-il si vous avez fourni un constructeur qui a initialisé le membre avec une ou plusieurs expressions de types différents?