¿Hay un objeto de función C++ estándar para desmontar un std:: pair?
boost tr1 (6)
Por la forma en que redactó su pregunta, no estoy seguro de si esta es una respuesta adecuada, pero pruebe boost::tie
(parte de la biblioteca Boost :: tuple). Funciona en std::pair
s también.
¿Alguien sabe si existe un objeto de función C ++ de facto (es decir, TR1 o Boost) para acceder a los elementos de un std :: pair? Dos veces en las últimas 24 horas he deseado tener algo así como la función de keys
para los hashes de Perl. Por ejemplo, sería bueno ejecutar std :: transform en un objeto std :: map y volcar todas las claves (o valores) a otro contenedor. Definitivamente podría escribir un objeto de función así, pero preferiría reutilizar algo que haya tenido muchos ojos en él.
Eche un vistazo a boost :: adaptadores. Hay adaptadores predefinidos para iterar sobre las claves o valores del mapa sin copiarlos en un contenedor intermedio.
boost :: bind se usa a menudo para adaptar contenedores std :: map para usar con algoritmos. Aquí hay un ejemplo:
void print_string(const std::string& s) {
std::cout << s << ''/n'';
}
std::map<int,std::string> my_map;
my_map[0]="Boost";
my_map[1]="Bind";
std::for_each(my_map.begin(), my_map.end(),
boost::bind(&print_string, boost::bind(
&std::map<int,std::string>::value_type::second,_1)));
boost::bind
es lo que buscas.
boost::bind(&std::pair::second, _1); // returns the value of a pair
Ejemplo:
typedef std::map<std::string, int> map_type;
std::vector<int> values; // will contain all values
map_type map;
std::transform(map.begin(),
map.end(),
std::back_inserter(values),
boost::bind(&map_type::value_type::second, _1));
¿Qué pasa con el uso de combinaciones de diferentes contenedores?
Por ejemplo, cuando quería dividir un vector en elementos contenidos en un mapa complementario y elementos que no estaban en el mapa complementario, utilicé lo siguiente:
typedef int DWORD;
typedef std::pair<std::string, bool> user_info;
typedef std::map<DWORD, user_info> USER_MAP;
typedef std::vector<DWORD> VEC_STAFF;
VEC_STAFF::iterator it = std::partition(Staff.begin(), Staff.end(), (bind(&USER_MAP::find, m_Users, _1) != m_Users.end()));
Ahora tengo un segundo problema: durante la ejecución de la aplicación, el status bool de user_info puede cambiar y, más adelante, quiero volver a particionar el vector con elementos que tienen un estado bool de verdadero en lugar de estar contenidos en el mapa complementario .
Sin embargo, parece que tengo un problema para acceder al segundo elemento de un par anidado.
Intenté lo siguiente, pero parece que no puedo acceder al par anidado.
CActiveUsers::VEC_STAFF::const_iterator itCurEnd = partition(Staff.begin(), Staff.end(), bind(&USER_MAP::value_type::second::second, bind(&USER_MAP::find, &m_Users, _1)) == true);
Una opción que no se sugirió es std::tr1::get
. Ver las secciones 6.1.2 y 6.1.4 de n1745 .
std::pair< std::string, int > p( "foo", 1729 );
int hr = std::tr1::get< 1 >( p );
Definitivamente no es tan fácil de usar como el bind
en el caso de extracción de map
que mencionas pero que aún vale la pena conocer. Adaptando el código de Johannes:
typedef std::map<std::string, int> map_type;
std::vector<int> values; // will contain all values
map_type map;
// std::tr1::get is overloaded so we need to help the compiler choose
const map_type::value_type::second_type & (*get)( const map_type::value_type & ) =
&std::tr1::get< 1, map_type::value_type::first_type, map_type::value_type::second_type >;
std::transform(map.begin(),
map.end(),
std::back_inserter(values),
get);