Posible error del compilador en MSVC

13

El siguiente código se compila con gcc y clang (y muchos otros compiladores de 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};
}

cuando se compila con (casi) el último 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

¿Es esto un error de MSVC? En caso afirmativo, ¿qué término en el estándar C ++ lo describe mejor?

Si reemplaza parte del código con

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

se compila sin problemas de todos modos.

Nube
fuente
Esta frase podría explicar las diferencias. Vea para qué regresan sus compiladores std::is_same_v<char, int8_t>. Supongo que es la implementación definida si int8_t es lo mismo que char, pero sería necesario verificar la documentación.
alter igel
Parece que de hecho puede ser un error. Este problema se abrió recientemente y ha habido varios otros informes.
instancia alterada el
1
@alteredinstance No veo cómo ese problema se relaciona con esta pregunta, o cómo lo hace su enlace anterior, para el caso. ¿Acabas de copiar el primer enlace que da Google para este mensaje de error? El mensaje de error es muy genérico y puede aparecer en muchas situaciones diferentes (legítimas).
nuez
@walnut La línea 231 del código mencionado en el problema tiene un enlace difunto a un problema de MSVC con inicialización agregada, lo mismo que está haciendo el código de OP. Da la casualidad de que la biblioteca de impulso se ha encontrado recientemente con un problema similar al usar valueun tipo agregado con
MSVC

Respuestas:

8

Diría que MSVC está equivocado al no aceptar el código.

De acuerdo con [dcl.fct.default] / 5 del borrador final estándar de C ++ 17, la búsqueda de nombres en los argumentos predeterminados de una función miembro de una plantilla de clase se realiza de acuerdo con las reglas en [temp.inst].

De acuerdo con [temp.inst] / 2 la creación de instancias implícita de una plantilla de clase no causa la creación de instancias de argumentos predeterminados de funciones miembro y de acuerdo con [temp.inst] / 4 un argumento predeterminado para una función miembro de una (especialización no explícita de a) la plantilla de clase se instancia cuando es utilizada por una llamada.

No hay ninguna llamada que utilice el argumento predeterminado to_datatype<T>::valueen su código y, por lo tanto, no se debe instanciar. Por lo tanto, no debería haber un error acerca de las operaciones de búsqueda de valueen to_datatype<char>su defecto.

(Las secciones relevantes en el borrador final estándar de C ++ 11 tienen una redacción equivalente, a excepción de la numeración, consulte [decl.fct.default] / 5 , [temp.inst] / 1 y [temp.inst] / 3 en su lugar).

nuez
fuente