Bogue du compilateur possible dans MSVC

13

Le code suivant se compile avec gcc et clang (et de nombreux autres compilateurs C ++ 11)

#include <stdint.h>

typedef int datatype;

template <typename T>
struct to_datatype {};

template <>
struct to_datatype<int16_t> {
  static constexpr datatype value = 1;
};

template <typename T>
class data {
 public:
  data(datatype dt = to_datatype<T>::value) {}
};

int main() {
  data<char> d{to_datatype<int16_t>::value};
}

lors de la compilation avec (presque) le dernier MSVC

> cl .\test.cpp /std:c++latest /permissive-
Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
.\test.cpp(16): error C2039: 'value': is not a member of 'to_datatype<T>'
        with
        [
            T=char
        ]
.\test.cpp(16): note: see declaration of 'to_datatype<T>'
        with
        [
            T=char
        ]
.\test.cpp(20): note: see reference to class template instantiation 'data<char>' being compiled

Est-ce un bug de MSVC? Si oui, quel terme dans la norme C ++ le décrit le mieux?

Si vous remplacez une partie du code par

template <typename T>
class data {
 public:
  data(datatype dt) {}
  data() : data(to_datatype<T>::value) {}
};

il se compile sans problème de toute façon.

Nuage
la source
Ce one-liner pourrait expliquer les différences. Découvrez les avantages de vos compilateurs std::is_same_v<char, int8_t>. Je suppose que c'est l'implémentation définie si int8_t est le même que char, mais il faudrait vérifier la documentation.
alter igel
Il semble que ce soit en fait un bug. Cette question a été ouverte récemment et il y a eu plusieurs autres rapports.
alteredinstance
1
@alteredinstance Je ne vois pas en quoi ce problème est lié à cette question, ni comment fonctionne votre lien précédent, d'ailleurs. Vous venez de copier le premier lien que Google donne pour ce message d'erreur? Le message d'erreur est très générique et peut apparaître dans de nombreuses situations différentes (légitimes).
noyer
@walnut La ligne 231 du code mentionné dans le problème a un lien défunt avec un problème MSVC avec initialisation agrégée, la même chose que le code OP fait. Il se trouve que la bibliothèque boost a récemment rencontré un problème similaire avec l'utilisation valuedans un type agrégé avec
MSVC
1
et un nouveau rapport de bug: developercommunity.visualstudio.com/content/problem/871304/…
marcinj

Réponses:

8

Je dirais que MSVC a tort de ne pas accepter le code.

Selon [dcl.fct.default] / 5 du projet final standard C ++ 17, la recherche de nom dans les arguments par défaut d'une fonction membre d'un modèle de classe se fait selon les règles de [temp.inst].

Selon [temp.inst] / 2, l' instanciation implicite d'un modèle de classe ne provoque pas l'instanciation des arguments par défaut des fonctions membres et selon [temp.inst] / 4 un argument par défaut pour une fonction membre d'un (spécialisation non explicite de a) le modèle de classe est instancié lorsqu'il est utilisé par un appel.

Il n'y a aucun appel utilisant l'argument par défaut to_datatype<T>::valuedans votre code et il ne doit donc pas être instancié. Par conséquent, il ne devrait pas y avoir d'erreur sur la recherche de valueen to_datatype<char>échec.

(Les sections pertinentes dans le projet final standard C ++ 11 ont un libellé équivalent, à l'exception de la numérotation, voir à la place [decl.fct.default] / 5 , [temp.inst] / 1 et [temp.inst] / 3. )

noyer
la source