for ejemplo c++ c++11 auto variable-declaration

ejemplo - Declaración automática de C++ 11 con y sin declarador de puntero



decltype (6)

¿Cuál es la diferencia entre los tipos de bar1 y bar2 ?

int foo = 10; auto bar1 = &foo; auto *bar2 = &foo;

Si tanto bar1 como bar2 son int* , ¿tiene sentido escribir el declarador de puntero ( * ) en la declaración bar2 ?


Como otros dijeron, generarán el mismo código. El asterisco es ruido de línea (y hace que sea más difícil cambiar de punteros crudos a punteros inteligentes si, por ejemplo, &foo alguna vez es reemplazado por get_foo() ). Si quieres ser explícito, entonces por supuesto, sé explícito; pero cuando usa la inferencia de tipo, simplemente deje que el compilador haga su trabajo. La falta de asteriscos no implica que un objeto no sea un puntero.


En este ejemplo específico, tanto bar1 como bar2 son lo mismo. Es una cuestión de preferencia personal, aunque diría que bar2 es más fácil de leer.

Sin embargo, esto no es válido para referencias como se ve en este example :

#include <iostream> using namespace std; int main() { int k = 10; int& foo = k; auto bar = foo; //value of foo is copied and loses reference qualifier! bar = 5; //foo / k won''t be 5 cout << "bar : " << bar << " foo : " << foo << " k : " << k << endl; auto& ref = foo; ref = 5; // foo / k will be 5 cout << "bar : " << bar << " foo : " << foo << " k : " << k; return 0; }


Hay una gran diferencia cuando usas clasificadores const :

int i; // Const pointer to non-const int const auto ip1 = &i; // int *const ++ip1; // error *ip1 = 1; // OK // Non-const pointer to const int const auto* ip2 = &i; // int const* ++ip2; // OK *ip2 = 1; // error


Las declaraciones son exactamente equivalentes. auto Works (casi) lo mismo que la deducción del tipo de plantilla . Poner la estrella explícitamente hace que el código sea un poco más fácil de leer, y hace que el programador sepa que bar2 es un puntero.


No importa en lo que respecta a la interpretación del código C ++; puedes escribir lo que quieras Sin embargo, hay una cuestión de estilo y legibilidad: en general, no debe ocultar apuntadores, referencias y calificadores de CV, y quizás incluso indicadores inteligentes, en alias de tipo, ya que hace que sea más difícil para el lector entender que eso es lo que está sucediendo. Los alias de tipo deben empaquetar el contenido de tipo semánticamente relevante, mientras que los calificadores y modificadores deben permanecer visibles. Entonces, prefiero lo siguiente:

using Foo = long_namespace::Foobrigation<other_namespace::Thing>; using MyFn = const X * (int, int); std::unique_ptr<Foo> MakeThatThing(MyFn & fn, int x) // or "MyFn * fn" { const auto * p = fn(x, -x); return p ? p->Create() : nullptr; }

Y no digas:

using PFoo = std::unique_ptr<Foo>; // just spell it out using MyFn = int(&)(int, int); // unnecessary; & is easy to spell auto p = fn(x, -x); // Don''t know that p is a pointer

Tenga en cuenta también que los calificadores de referencia (a diferencia de los punteros) realmente cambian el tipo de la variable que se está declarando, por lo que no son opcionales:

X & f(); auto a = f(); // copy! auto & b = f(); // b is the same as the return value of f()

Finalmente, agregar calificaciones explícitas de const pointer puede ayudar a corregir errores. Considere el siguiente ejemplo, en el cual un contenedor contiene punteros-a-mutable, pero solo requerimos acceso const. Just auto * deduciría un puntero a mutable, lo que podemos evitar diciendo const explícitamente:

std::vector<X*> v = /* ... */; for (const auto * p : v) { observe(p->foo()); // no need for a mutable *p }


Usar auto * "intención de documentos". Y auto *p = expr; se puede deducir correctamente solo si expr devuelve el puntero. Ejemplo:

int f(); auto q = f(); // OK auto *p = f(); // error: unable to deduce ''auto*'' from ''f()''