2009-05-07 16 views
12

Tengo un vector de punteros que no son propiedad del contenedor. ¿Cómo uso los algoritmos en los objetivos de los punteros? Traté de usar boost ptr_vector, pero intenta eliminar los punteros cuando sale del alcance.cómo se usan los algoritmos STL con un vector de punteros

Aquí hay un código que tiene que trabajar:

vector<int*> myValues; 
// ... myValues is populated 
bool consistent = count(myValues.begin(), myValues.end(), myValues.front()) == myValues.size(); 
auto v = consistent ? myValues.front() : accumulate(myValues.begin(), myValues.end(), 0)/myValues.size(); 
fill(myValues.begin(), myValues.end(), v); 
// etc. 

Soy consciente de que para los bucles que funcionaría, pero esto sucede en un montón de lugares, por lo que algún tipo de adaptador unario? No pude encontrar uno. ¡Gracias por adelantado!

+0

Si utiliza las características del futuro estándar de C++ pendiente de aprobación en sus preguntas, limitará las respuestas que obtenga. No está muy claro si su pregunta es acerca de la biblioteca estándar actual, el uso de Boost o las nuevas características de C++ 0x. –

+0

Parece que se supone que v es el valor promedio de los enteros, pero luego la línea de copia intenta copiar a v, por lo que v tendría que ser un puntero o un iterador. –

+0

oh sí, esa última línea era incorrecta ... Tenía la intención de escribir "llenar" en lugar de "copiar". –

Respuesta

19

Puede usar Boost Indirect Iterator. Cuando se desreferencia (con operator*()), se aplica una desreferencia adicional, por lo que se termina con el valor apuntado por el puntero al que hace referencia el iterador. Para obtener más información, también puede ver this question about a dereference iterator.

Aquí está un ejemplo sencillo:

std::vector<int*> vec; 

vec.push_back(new int(1)); 
vec.push_back(new int(2)); 

std::copy(boost::make_indirect_iterator(vec.begin()), 
      boost::make_indirect_iterator(vec.end()), 
      std::ostream_iterator<int>(std::cout, " "));  // Prints 1 2 
+0

Esto es exactamente lo que estaba buscando, ¡gracias! –

+0

oh, bien, esa fue su pregunta - forma de transmitir el conocimiento;) –

0

Puede mirar boost::shared_ptr<> - un puntero inteligente con recuento de referencias. No eliminará el puntero una vez que salga del alcance.

+0

el problema es que los punteros son variables miembro en otros objetos. Podría convertirlos en shared_ptr también, pero esa podría no ser la forma más eficiente de hacerlo. –

3
bool consistent = count_if(myValues.begin(), myValues.end(), 
    bind2nd(ptr_fun(compare_ptr), *myValues.front())) == myValues.size(); 

int v = consistent ? *myValues.front() : accumulate(
    myValues.begin(), myValues.end(), 0, sum_int_ptr)/myValues.size(); 

for_each(myValues.begin(), myValues.end(), bind1st(ptr_fun(assign_ptr),v)); 

de relleno no puede asignar la función (por lo que sería eliminar la referencia de punteros). Por lo tanto, se utilizó for_each(). Para la optimización, sería aconsejable agregar if (! Consistente) antes de ejecutar for_each(). Funciones usadas en líneas superiores de STL anteriores:

int sum_int_ptr(int total, int * a) { return total + *a; }  
void assign_ptr(int v, int *ptr) { *ptr = v; }  
bool compare_ptr(int* a, int pattern) { return *a == pattern; } 
+1

Gracias, aprendí mucho de su respuesta. Probablemente vaya con los iteradores indirectos impulso aquí, pero es bueno saber cómo usar bind1st, bind2nd, y así sucesivamente. –

+0

Sí, STL es bastante poderoso, vale la pena conocer todos estos lineamientos como acumular, etc. –

+1

PD .: Worth reading: http://www.keithschwarz.com/cs106l/fall2007/handouts/200_STL_Functional_Library.pdf –

Cuestiones relacionadas