2011-10-05 12 views
17

Estoy buscando un poco de ayuda en la siguiente situación:
tengo alguna clase y un método en el que, la sintaxis es la siguiente:cuerpo de inicialización de la matriz como parámetro de función (C-array), ¿es posible?

class SomeClass { 
    public: 
      void doSomething(int *a); 
}; 

por lo que quiero llamar a este método como

SomeClass::doSomething({ 0, 1, 2, 3, 4 }); 

¿Es posible en cualquier idioma? ¡Cualquier implementación (C++, C, obj-c, obj-C++) es bienvenida! sé que este bloque de inicialización es un cuerpo de matriz, como

int *a = { 0, 1, 2, 3, 4 }; 
SomeClass::doSomething(a); 

Pero interfaz se ven muy bien, creo que, si va a haber ninguna variable temp antes de las llamadas de función (ya que no necesitamos saber el tipo de parámetro en class-client). Entonces, ¿hay alguna posibilidad de hacer esto?

Respuesta

8

Esto es sobre C++ 11 initializer lists (sección 18.9).

void foo (std :: initializer_list <int> inputs) { 
    for (auto i : inputs) { 
     // ... 
    } 
} 

foo ({10, 20, 30}); 

Sólo el compilador puede crear una lista de inicialización, pero se puede tratar como un contenedor de estilo STL estándar con iteradores begin(), end(), size(), y de acceso aleatorio.

std::vector (y espero que algunos otros contenedores) ahora puede ser construido con las listas de inicializador, por lo

std :: vector <std :: string> foo {"a", "b"}; 

es equivalente a

std :: vector <std :: string> foo; 
foo .push_back ("a"); 
foo .push_back ("b"); 

excepto que puede realizar un menor número de asignaciones. Tenga en cuenta que el const char* se ha convertido automáticamente en std::string.

+0

En realidad, esto funcionará con * cualquier * clase de contenedor, gracias a la inicialización uniforme de C++ 11. –

20

En este C99 funciona:

functionThatTakesIntPtrOrArray((int []){ 1, 2, 3, 4 }); 

..y cosas similares se puede hacer con estructuras.

+0

muchas gracias, ¡me salvó mucha paciencia! –

+2

Lamentablemente no funciona en C++. Obtiene el error "tomar la dirección de la matriz temporal". – Timmmm

+0

No funciona en Visual Studio 2017 (v141) – sergiol

2

Si initializer_list no está disponible, y las matrices son en su mayoría pequeñas, no hay otra opción, la sobrecarga << operador para std :: vector de la siguiente manera:

template <typename T> 
inline std::vector<T> operator <<(const std::vector<T>& vec, const T& val) { 
    std::vector<T> result(vec); 
    result.push_back(val); 
    return result; 
} 

Con esto, usted puede hacer esto:

void foo (const std::vector<int>& inputs) { 
    // ... 
} 

foo (std::vector<int>() << 10 << 20 << 30); 

Hay un precio a pagar por esta conveniencia de la inicialización de una sola línea y no tener que especificar el tamaño del vector. Se crea una copia del vector anterior para cada elemento que se agrega, lo que hace que el tiempo de ejecución sea al menos cuadrático en tamaño vectorial; por eso, es el más adecuado para vectores cortos y casos en los que el rendimiento no es importante. Hay una mejor solución para C++ 11, como se señala en la respuesta de spraff.

Cuestiones relacionadas