new - vector vector c++




¿Cuál es la forma más fácil de inicializar un std:: vector con elementos codificados? (17)

Puedo crear una matriz e inicializarla de esta manera:

int a[] = {10, 20, 30};

¿Cómo creo un std::vector y lo inicializo de manera similar?

La mejor manera que conozco es:

std::vector<int> ints;

ints.push_back(10);
ints.push_back(20);
ints.push_back(30);

¿Hay alguna manera mejor?


Antes de C ++ 11:

Método 1 =>

vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));
vector<int>v;

Método 2 =>

 v.push_back(SomeValue);

C ++ 11 en adelante también es posible

vector<int>v = {1, 3, 5, 7};

B. Stroustrup describe una buena manera de encadenar operaciones en 16.2.10 Selfreference en la página 464 en la edición C ++ 11 del Prog. Lang. donde una función devuelve una referencia, aquí modificada a un vector. De esta manera puedes encadenar como v.pb(1).pb(2).pb(3); pero puede ser demasiado trabajo para tan pequeñas ganancias.

#include <iostream>
#include <vector>

template<typename T>
class chain
{
private:
    std::vector<T> _v;
public:
    chain& pb(T a) {
        _v.push_back(a);
        return *this;
    };
    std::vector<T> get() { return _v; };
};

using namespace std;

int main(int argc, char const *argv[])
{
    chain<int> v{};

    v.pb(1).pb(2).pb(3);

    for (auto& i : v.get()) {
        cout << i << endl;
    }

    return 0;
}

1
2
3


Empezando con:

int a[] = {10, 20, 30}; //i'm assuming a is just a placeholder

Si no tienes un compilador de C ++ 11 y no quieres usar boost:

const int a[] = {10, 20, 30};
const std::vector<int> ints(a,a+sizeof(a)/sizeof(int)); //make it const if you can

Si no tienes un compilador de C ++ 11 y puedes usar boost:

#include <boost/assign.hpp>
const std::vector<int> ints = boost::assign::list_of(10)(20)(30);

Si tienes un compilador de C ++ 11:

const std::vector<int> ints = {10,20,30};

En C ++ 0x podrá hacerlo de la misma manera que lo hizo con una matriz, pero no en el estándar actual.

Con solo soporte de idioma puedes usar:

int tmp[] = { 10, 20, 30 };
std::vector<int> v( tmp, tmp+3 ); // use some utility to avoid hardcoding the size here

Si puedes agregar otras bibliotecas, puedes probar boost :: tarea:

vector<int> v = list_of(10)(20)(30);

Para evitar codificar el tamaño de una matriz:

// option 1, typesafe, not a compile time constant
template <typename T, std::size_t N>
inline std::size_t size_of_array( T (&)[N] ) {
   return N;
}
// option 2, not typesafe, compile time constant
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))

// option 3, typesafe, compile time constant
template <typename T, std::size_t N>
char (&sizeof_array( T(&)[N] ))[N];    // declared, undefined
#define ARRAY_SIZE(x) sizeof(sizeof_array(x))

En C ++ 11:

static const int a[] = {10, 20, 30};
vector<int> vec (begin(a), end(a));

Hay muchas respuestas buenas aquí, pero como llegué a mi cuenta de forma independiente antes de leer esto, pensé que de todos modos tiraría la mía aquí ...

Aquí hay un método que estoy usando para esto que funcionará universalmente en compiladores y plataformas:

Cree una estructura o clase como contenedor para su colección de objetos. Defina una función de sobrecarga del operador para <<.

class MyObject;

struct MyObjectList
{
    std::list<MyObject> objects;
    MyObjectList& operator<<( const MyObject o )
    { 
        objects.push_back( o );
        return *this; 
    }
};

Puede crear funciones que tomen su estructura como un parámetro, por ejemplo:

someFunc( MyObjectList &objects );

Entonces, puedes llamar a esa función, así:

someFunc( MyObjectList() << MyObject(1) <<  MyObject(2) <<  MyObject(3) );

De esa manera, puede crear y pasar una colección de objetos de tamaño dinámico a una función en una sola línea limpia.


Los siguientes métodos pueden utilizarse para inicializar el vector en c ++.

  1. int arr[] = {1, 3, 5, 6}; vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));

  2. vector<int>v; v.push_back(1); v.push_back(2); v.push_back(3); y así

  3. vector<int>v = {1, 3, 5, 7};

El tercero solo está permitido en C ++ 11 en adelante.


Para inicialización de vectores -

vector<int> v = {10,20,30}

Se puede hacer si tienes el compilador de c ++ 11.

De lo contrario, puede tener una matriz de datos y luego usar un bucle for.

int array[] = {10,20,30}
for(int i=0; i<sizeof(array); i++)
     v.push_back(array[i]);

Aparte de estos, hay varias otras formas descritas anteriormente usando algún código. En mi opinión, estas formas son fáciles de recordar y rápidas de escribir.


Relacionado, puede usar lo siguiente si desea tener un vector completamente listo para usar en una declaración rápida (por ejemplo, pasar inmediatamente a otra función):

#define VECTOR(first,...) \
   ([](){ \
   static const decltype(first) arr[] = { first,__VA_ARGS__ }; \
   std::vector<decltype(first)> ret(arr, arr + sizeof(arr) / sizeof(*arr)); \
   return ret;})()

función de ejemplo

template<typename T>
void test(std::vector<T>& values)
{
    for(T value : values)
        std::cout<<value<<std::endl;
}

ejemplo de uso

test(VECTOR(1.2f,2,3,4,5,6));

aunque tenga cuidado con el tipo de letra, asegúrese de que el primer valor sea claramente lo que desea.


Si desea algo en el mismo orden general que Boost :: assign sin crear una dependencia en Boost, lo siguiente es al menos vagamente similar:

template<class T>
class make_vector {
    std::vector<T> data;
public:
    make_vector(T const &val) { 
        data.push_back(val);
    }

    make_vector<T> &operator,(T const &t) {
        data.push_back(t);
        return *this;
    }

    operator std::vector<T>() { return data; }
};

template<class T> 
make_vector<T> makeVect(T const &t) { 
    return make_vector<T>(t);
}

Aunque deseo que la sintaxis para usarla sea más limpia, todavía no es particularmente horrible:

std::vector<int> x = (makeVect(1), 2, 3, 4);

Si no quieres usar boost, pero quieres disfrutar de la sintaxis como

std::vector<int> v;
v+=1,2,3,4,5;

solo incluye este trozo de código

template <class T> class vector_inserter{
public:
    std::vector<T>& v;
    vector_inserter(std::vector<T>& v):v(v){}
    vector_inserter& operator,(const T& val){v.push_back(val);return *this;}
};
template <class T> vector_inserter<T> operator+=(std::vector<T>& v,const T& x){
    return vector_inserter<T>(v),x;
}

Si su compilador admite macros Variadic (lo cual es cierto para la mayoría de los compiladores modernos), entonces puede usar la siguiente macro para convertir la inicialización de vectores en una sola línea:

#define INIT_VECTOR(type, name, ...) \
static const type name##_a[] = __VA_ARGS__; \
vector<type> name(name##_a, name##_a + sizeof(name##_a) / sizeof(*name##_a))

Con esta macro, puede definir un vector inicializado con un código como este:

INIT_VECTOR(int, my_vector, {1, 2, 3, 4});

Esto crearía un nuevo vector de entradas llamado my_vector con los elementos 1, 2, 3, 4.


Solo pensé en tirar mis $ 0.02. Tiendo a declarar esto:

template< typename T, size_t N >
std::vector<T> makeVector( const T (&data)[N] )
{
    return std::vector<T>(data, data+N);
}

en un encabezado de utilidad en algún lugar y luego todo lo que se requiere es:

const double values[] = { 2.0, 1.0, 42.0, -7 };
std::vector<double> array = makeVector(values);

Pero no puedo esperar a C ++ 0x. Estoy atascado porque mi código también debe compilar en Visual Studio. Abucheo.


Un método sería utilizar la matriz para inicializar el vector

static const int arr[] = {16,2,77,29};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );

puedes hacerlo usando boost :: assign.

vector<int> values;  
values += 1,2,3,4,5,6,7,8,9;

detalle aqui


"¿Cómo creo un vector STL y lo inicializo como el anterior? ¿Cuál es la mejor manera de hacerlo con el mínimo esfuerzo de escritura?"

La forma más fácil de inicializar un vector, ya que ha inicializado su matriz integrada, es utilizando una lista de inicializadores que se introdujo en C ++ 11 .

// Initializing a vector that holds 2 elements of type int.
Initializing:
std::vector<int> ivec = {10, 20};


// The push_back function is more of a form of assignment with the exception of course
//that it doesn't obliterate the value of the object it's being called on.
Assigning
ivec.push_back(30);

ivec tiene 3 elementos de tamaño después de que se ejecuta la Asignación (declaración etiquetada).


typedef std::vector<int> arr;

arr a {10, 20, 30};       // This would be how you initialize while defining

Para compilar el uso:

clang++ -std=c++11 -stdlib=libc++  <filename.cpp>




initialization