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.
c++
c++11
visual-c++
Nube
fuente
fuente
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.value
un tipo agregado conRespuestas:
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>::value
en 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 devalue
ento_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).
fuente