to_int strtoint stoi parse numeros not convertir como c++ stl

c++ - strtoint - std:: par de referencias



stoi is not a member of std (7)

Creo que sería legal tener referencias std::pair vivienda. std::map usa std::pair con un tipo const , después de todo, que no se puede asignar a ninguno.

Me gustaría tener un pair<T&, U&> y poder asignarle otro par

La asignación no funcionará, ya que no puede restablecer las referencias. Sin embargo, puede copiar-inicializar tales objetos.

¿Es válido tener un std::pair de referencias? En particular, ¿hay problemas con el operador de asignación? De acuerdo con este enlace , no parece haber un tratamiento especial con operator =, por lo que no se podrá generar el operador de asignación predeterminado.

Me gustaría tener un pair<T&, U&> y poder asignarle otro par (de valores o referencias) y modificar los objetos apuntados.


En C ++ 11 puede usar std::pair< std::reference_wrapper <T>, std::reference_wrapper<U>> y los objetos de ese tipo se comportarán exactamente como lo desee.


No sé qué está "mal" con std::pair en C ++ 03 pero si lo vuelvo a implementar ingenuamente, no tengo ningún problema con él, (usando el mismo compilador gcc y clang ).

double a = 1.; double b = 2.; my::pair<double, double> p1(5., 6.); my::pair<double&, double&> p2(a, b); p2 = p1; // a == 5.

Así que una solución podría ser (1) reimplementar el pair (en un espacio de nombre diferente), o (2) especializar para std::pair<T&, T&> , o (3) simplemente usar C ++ 11 (donde std::pair para refs funciona fuera de la caja)

(1) Aquí está la implementación ingenua

namespace my{ template<class T1, class T2> struct pair{ typedef T1 first_type; typedef T2 second_type; T1 first; T2 second; pair(T1 const& t1, T2 const& t2) : first(t1), second(t2){} template<class U1, class U2> pair(pair<U1, U2> const& p) : first(p.first), second(p.second){} template<class U1, class U2> pair& operator=(const pair<U1, U2>& p){ first = p.first; second = p.second; return *this; } }; template<class T1, class T2> pair<T1, T2> make_pair(T1 t1, T2 t2){ return pair<T1, T2>(t1, t2); } }

(2) Y aquí está una especialización de std::pair (algunas personas pueden quejarse de que estoy molestando sobrecargar / especializarme con el std nombres std , pero creo que está bien si es para extender las capacidades de la clase)

namespace std{ template<class T1, class T2> struct pair<T1&, T2&>{ typedef T1& first_type; /// @c first_type is the first bound type typedef T2& second_type; /// @c second_type is the second bound type first_type first; second_type second; pair(T1& t1, T2& t2) : first(t1), second(t2){} template<class U1, class U2> pair(pair<U1, U2> const& p) : first(p.first), second(p.second){} template<class U1, class U2> pair& operator=(const pair<U1, U2>& p){ first = p.first; second = p.second; return *this; } }; }

Tal vez me está perdiendo algo obvio, puedo editar la respuesta si algunos defectos obvios son puntiagudos.


No, no puede hacer esto de manera confiable en C ++ 03, porque el constructor de pair toma referencias a T , y crear una referencia a una referencia no es legal en C ++ 03.

Tenga en cuenta que dije "de manera confiable". Algunos compiladores comunes todavía en uso (para GCC, probé GCC4.1, @Charles informaron GCC4.4.4) no permiten formar una referencia a una referencia, pero más recientemente lo permiten a medida que implementan colapso de referencia ( T& T es T si T es un tipo de referencia). Si su código usa tales cosas, no puede confiar en que funcione en otros compiladores hasta que lo pruebe y vea.

Parece que quieres usar boost::tuple<>

int a, b; // on the fly boost::tie(a, b) = std::make_pair(1, 2); // as variable boost::tuple<int&, int&> t = boost::tie(a, b); t.get<0>() = 1; t.get<1>() = 2;


Pensaba en la misma línea que tú, creo. Escribí la siguiente clase para borrar este particular picor:

template <class T1, class T2> struct refpair{ T1& first; T2& second; refpair(T1& x, T2& y) : first(x), second(y) {} template <class U, class V> refpair<T1,T2>& operator=(const std::pair<U,V> &p){ first=p.first; second=p.second; return *this; } };

Te permite hacer cosas horribles como:

int main (){ int k,v; refpair<int,int> p(k,v); std::map<int,int>m; m[20]=100; m[40]=1000; m[60]=3; BOOST_FOREACH(p,m){ std::cout << "k, v = " << k << ", " << v << std::endl; } return 0; }

(recuerde que el relevante incluye).

La maldad es, por supuesto, que las referencias a k y v que estoy asignando están ocultas dentro de p . Casi se vuelve bonito de nuevo si haces algo como esto:

template <class T1,class T2> refpair<T1,T2> make_refpair (T1& x, T2& y){ return ( refpair<T1,T2>(x,y) ); }

Lo cual te permite hacer un loop así:

BOOST_FOREACH(make_refpair(k,v),m){ std::cout << "k, v = " << k << ", " << v << std::endl; }

(Todos los comentarios son bienvenidos, ya que de ninguna manera soy un experto en C ++).


Terminé resolviendo un problema similar al construir una estructura realmente simple. Ni siquiera me preocupé por el operador de asignación, ya que el predeterminado debería funcionar bien.

template<class U, class V> struct pair { pair(U & first, V & second): first(first), second(second) {} U & first; V & second; }


Tienes razón. Puede crear un par de referencias, pero ya no puede usar operator = .