"Aplicación en profundidad de optimización de código C ++ 11 y aplicación de nivel de ingeniería" Capítulo 1 registro de aprendizaje
1.1 Tipo de deducción
1.1.1 deducción automática de tipo
Auto no representa una declaración de tipo real, solo un "marcador de posición" para la declaración de tipo.
Las variables declaradas usando auto deben inicializarse inmediatamente para permitir que el compilador deduzca su tipo real y reemplace el marcador de posición automático con el tipo real en tiempo de compilación.
Las reglas de derivación de auto : (calificador cv: const y volátil colectivamente)
(1) Cuando no se declara como puntero o referencia, el resultado de derivación de auto y la expresión de inicialización descartan la referencia y el tipo del calificador cv.
p.ej. int x = 0;
const self e = x; // e-> const int
auto f = e; // f-> int
(2) Cuando se declara como puntero o referencia, el resultado de derivación de auto mantendrá el atributo cv de la expresión.
eg.int x = 0;
const auto & g = x; // g-> const int &
auto h = g; // h-> const int &
Limitaciones de auto :
(1) Auto no se puede usar para parámetros de función.
(2) Auto no se puede usar para variables miembro no estáticas.
(3) Automático no puede definir una matriz.
(4) Auto no puede derivar parámetros de plantilla.
p.ej.
[root @ 192 C ++ 11] # cat funcautodemo.cpp
#include <iostream>
usando namespace std;
struct Foo
{
auto var1_ = 0; // auto no se puede usar para variables miembro no estáticas
static const auto var2_ = 0;
};
int func (auto x) // auto no se puede usar para parámetros de función
{
int i = x;
return 0;
}
plantilla <typename T> struct Bar {};
int main ()
{
int arr [10] = {0};
auto aa = arr;
auto rr [10] = arr; // auto no puede definir la matriz
Bar <int> bar;
Bar <auto> bb = bar; // auto no puede derivar el
retorno de parámetro de plantilla 0;
}
[root @ 192 C ++ 11] # g ++ funcautodemo.cpp -o funcautodemo -std = c ++ 11
funcautodemo.cpp: 5: 5: error: miembro de datos no estático declarado con marcador de posición 'auto'
5 | auto var1_ = 0;
| ^ ~~~
funcautodemo.cpp: 9: 10: error: el uso de 'auto' en la declaración de parámetros solo está disponible con '-std = c ++ 14' o '- std = gnu ++ 14 '
9 | int func (auto x)
| ^ ~~~
funcautodemo.cpp: En la función' int main () ':
funcautodemo.cpp: 21: 10: error: ' rr 'declarado como matriz de 'auto'
21 | auto rr [10] = arr;
El | ^ ~
funcautodemo.cpp: 24: 9: error: uso no válido de 'auto'
24 | Bar <auto> bb = bar;
El | ^ ~~~
funcautodemo.cpp: 24: 13: error: el argumento de plantilla 1 no es válido
24 | Bar <auto> bb = bar;
El | ^
funcautodemo.cpp: 24: 20: error: no se puede convertir 'Bar <int>' a 'int' en la inicialización
24 | Bar <auto> bb = bar;
El | ^ ~~
| El |
El | Barra <int>
1.1.2 La palabra clave decltype
Obtener el tipo de expresión
El auto mencionado anteriormente necesita inicializar las variables antes de que el compilador pueda deducir el tipo. Si no desea inicializar, puede obtener el tipo simplemente declarándolo, entonces necesita usar decltype.
p.ej.
int x = 0;
decltype (x) y = 1; // y-> int
decltype (x + y) z = 0; // z-> int
const int & i = x;
decltype (i) j = y; // j-> const int &
const decltype (z) * p = & z; // p-> const int *
decltype (z) * pi = & z; // pi-> int *
decltype (pi) * pp = & pi; // pp-> const int **
Reglas de derivación de declive (exp):
(1) exp es el identificador, la expresión de acceso de clase, decltype (exp) y exp son del mismo tipo
p.ej.
clase Foo
{
público:
static const int Número = 0;
int x = 0;
};
int n = 0;
const volátil int & x = n;
decltype (n) a = n; // a-> int
decltype (x) b = n; // b-> volatile const int &
decltype (Foo :: Number) c = 0; // c-> const int
Foo Foo;
decltype (foo.x) d = 0; // d-> int
(2) exp es una llamada de función, el tipo de decltype (exp) y el valor de retorno son los mismos
p.ej.
int & func_int_r (void); // Lvalue
int && func_int_rr (void); // Valor correcto
int func_int (void); // Valor puro
const int & func_cint_r (void); // Lvalue
const int && func_cint_rr (void); // Rvalue
const int func_cint (void); // Valor puro
const Foo func_cfoo (void); // Valor puro
int x = 0;
decltype (func_int_r ()) a1 = x; // a1-> int &
decltype (func_int_rr ()) b1 = 0; // b1-> int &&
decltype (func_int ()) c1 = 0; c1-> int
decltype (func_cint_r ()) a2 = x; // a2-> const int &
decltype (func_cint_rr ()) b2 = 0; // b2-> const int &&
decltype (func_cint ()) c2 = 0; // c2-> int
decltype (func_cfoo ()) ff = Foo (); // ff-> const Foo
Nota: c2 es int, const se ignora y ff es const Foo, const no se ignora, porque de acuerdo con la descripción en la especificación C ++ 11, el int devuelto por la función es un valor puro, solo el tipo de clase puede llevar cv Calificadores, otros generalmente ignoran el calificador cv.
(3) En otros casos, si exp es un valor de l, entonces dectype (exp) es una referencia de valor de tipo exp, de lo contrario es coherente con el tipo exp. .
p.ej.
struct Foo {int x;};
const Foo foo = Foo ();
decltype (foo.x) a = 0; // a-> int
decltype ((foo.x)) b = a; // b-> const int &
int n = 0, m = 0;
decltype (n + m) c = 0; // c-> int
decltype (n + = m) d = c; // d-> int &