Estoy tratando de almacenar un puntero compartido en una matriz de tamaño fijo en un vector, quiero usar un puntero compartido porque debo pasar un puntero a la matriz a otra clase que escribirá en la matriz, y quiero tener más de una matriz porque puedo tener más instancias de la clase de escritura y cada una necesita una matriz para escribir, escribirán muchos datos en las matrices, por lo que moverlos no es una buena opción.

std::shared_ptr<char> sp( new char [MAX_LENGTH], std::default_delete<  char[] >() );
arrayVect.push_back(sp);

El vector se define como miembro de la clase como:

std::vector< std::shared_ptr< char [ MAX_LENGTH ] > > arrayVect;

Estoy recibiendo el error:

 error: no matching function for call to ‘std::vector<std::shared_ptr<char [MAX_LENGTH]> >::push_back(std::shared_ptr<char []>&)’

He intentado diferentes alternativas, pero ninguna de ellas ha funcionado, ¿podría señalar la forma correcta de hacerlo? o hay una alternativa que me estoy perdiendo? la clase de escritura necesita una matriz de caracteres para la función de escritura, así que creo que estoy atascado con la matriz.

¡Gracias!

1
JD.gg 25 abr. 2017 a las 13:42

3 respuestas

La mejor respuesta

Siento que la propiedad compartida es el modelo equivocado aquí. Conceptualmente, ¿por qué querría que sus trabajadores continuaran trabajando en una matriz si nadie más observa el resultado?

Así que tendría arrayVect dueño de las matrices y entregaría punteros a las matrices a los trabajadores. Cuando no tenga sentido mantener una de las matrices, primero detenga al trabajador y luego elimine la matriz.

La forma más fácil de obtener ese comportamiento es hacer arrayVect a std::vector<std::unique_ptr<std::array<char, MAX_LENGTH>>>. Luego, puede obtener el puntero a la matriz subyacente char[MAX_LENGTH] que puede pasar a un trabajador llamando a arrayVect[idx].get().data().

Al tener la indirección adicional a través de unique_ptr, los punteros a las matrices siguen siendo válidos incluso si se cambia el tamaño del vector.

EDITAR: Aquí hay un ejemplo de cómo eso puede funcionar con unique_ptr s a pesar de que sus trabajadores también necesitan un puntero a la matriz:

class Worker {
public:
    Worker(std::array<char, MAX_SIZE>* array)
        : _array{array} {
    }

    void perform_work() {
       function_that_requires_c_arrays(_array->data()); // maybe also a size parameter? 
    }

private:    
    std::array<char, MAX_SIZE>* _array;
};

int main() {
    std::vector<std::unique_ptr<std::array<char, MAX_SIZE>>> arrayVect;
    arrayVect.emplace_back(std::make_unique<std::array<char, MAX_SIZE>>()));

    Worker w{arrayVect.back().get()};
    w.perform_work();
}
2
Corristo 25 abr. 2017 a las 11:36

Puede usar std::vector<std::shared_ptr<char>> sin la notación de matriz. Es importante que aún use std::default_delete<char[]>() como eliminador. Aquí hay un ejemplo completo.

#include <iostream>
#include <vector>
#include <memory>

#define MAX_LENGTH 10

int main() {
    std::vector<std::shared_ptr<char>> arrayVect;
    std::shared_ptr<char> sp(new char[MAX_LENGTH], std::default_delete<char[]>());
    arrayVect.push_back(sp);
    arrayVect.push_back(std::shared_ptr<char>(new char[MAX_LENGTH], std::default_delete<char[]>()));

    char q = 0;
    for (size_t x = 0; x < arrayVect.size(); ++x)
        for (size_t y = 0; y < MAX_LENGTH; ++y)
            arrayVect.at(x).get()[y] = ++q;

    for (size_t x = 0; x < arrayVect.size(); ++x)
        for (size_t y = 0; y < MAX_LENGTH; ++y)
            std::cout << int(arrayVect.at(x).get()[y]) << '\n'; // Int cast to print numbers, and not ASCII control characters
}
1
Jonas 25 abr. 2017 a las 11:11

Intenta declarar el vector como a continuación,

std::vector<std::shared_ptr<char> > arrayVect;

En realidad, estás declarando el vector incorrectamente. Por favor, intente y verifique con el cambio anterior. ¡Espero eso ayude!

1
Malcolm McLean 25 abr. 2017 a las 11:01