Möglicher Compilerfehler in MSVC

13

Der folgende Code wird mit gcc und clang (und vielen anderen C ++ 11-Compilern) kompiliert.

#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};
}

beim Kompilieren mit (fast) neuestem 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

Ist das ein Fehler von MSVC? Wenn ja, welcher Begriff im C ++ - Standard beschreibt ihn am besten?

Wenn Sie einen Teil des Codes durch ersetzen

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

es kompiliert sowieso reibungslos.

Wolke
quelle
Dieser Einzeiler könnte die Unterschiede erklären. Sehen Sie, wofür Ihre Compiler zurückkehren std::is_same_v<char, int8_t>. Ich würde vermuten, dass die Implementierung definiert ist, ob int8_t mit char identisch ist, aber man müsste die Dokumentation überprüfen.
Alter igel
Sieht so aus, als wäre es tatsächlich ein Fehler. Dieses Problem wurde kürzlich eröffnet und es gab mehrere andere Berichte.
Geänderte Instanz
1
@alteredinstance Ich sehe nicht, wie sich dieses Problem auf diese Frage bezieht oder wie Ihr vorheriger Link diesbezüglich funktioniert. Haben Sie gerade den ersten Link kopiert, den Google für diese Fehlermeldung gibt? Die Fehlermeldung ist sehr allgemein gehalten und kann in vielen verschiedenen (legitimen) Situationen auftreten.
Walnuss
@walnut Zeile 231 des in der Ausgabe erwähnten Codes enthält einen nicht mehr funktionierenden Link zu einem MSVC-Problem mit aggregierter Initialisierung, genau wie der Code von OP. Es ist einfach so, dass die Boost-Bibliothek kürzlich auf ein ähnliches Problem bei der Verwendung valueeines Aggregattyps mit MSVC gestoßen ist
Instanz

Antworten:

8

Ich würde sagen, dass MSVC falsch ist, den Code nicht zu akzeptieren.

Gemäß [dcl.fct.default] / 5 des endgültigen C ++ 17-Standardentwurfs erfolgt die Namenssuche in Standardargumenten einer Mitgliedsfunktion einer Klassenvorlage gemäß den Regeln in [temp.inst].

Gemäß [temp.inst] / 2 bewirkt die implizite Instanziierung einer Klassenvorlage keine Instanziierung von Standardargumenten von Elementfunktionen und gemäß [temp.inst] / 4 ein Standardargument für eine von a (nicht explizite Spezialisierung von a) Die Klassenvorlage wird instanziiert, wenn sie von einem Aufruf verwendet wird.

Es gibt keinen Aufruf mit dem Standardargument to_datatype<T>::valuein Ihrem Code und sollte daher nicht instanziiert werden. Daher sollte es nicht ein Fehler sein , etwa von Nachschlag valuein to_datatype<char>scheitern.

(Die relevanten Abschnitte im endgültigen C ++ 11-Standardentwurf haben einen gleichwertigen Wortlaut, mit Ausnahme der Nummerierung, siehe stattdessen [decl.fct.default] / 5 , [temp.inst] / 1 und [temp.inst] / 3. )

Nussbaum
quelle