sintaxis - ¿Debo usar las características de C++ 0x ahora?
sintaxis de c++ (6)
Supongo que estoy preguntando si hay alguna posibilidad de que VC ++ 2010 o GCC terminen como VC ++ 6; se publicó antes de que el idioma se estandarizara oficialmente y, por lo tanto, se permitía compilar el código mal formado.
Es posible que suceda, pero muy improbable, en mi humilde opinión. No solo MS, sino que otros proveedores de compiladores también están soportando algunas características de C ++ 0x y espero que el Comité Estándar sea extremadamente cuidadoso al romper la compatibilidad en este punto.
Con el lanzamiento oficial de VS 2010, ¿es seguro para mí comenzar a usar el conjunto de funciones C ++ 0x implementado parcialmente en mi nuevo código?
Las características que me interesan en este momento están implementadas por VC ++ 2010 y las versiones recientes de GCC. Estos son los dos únicos que tengo que apoyar.
En términos de la "seguridad" mencionada en la primera oración: ¿puedo comenzar a usar estas funciones (por ejemplo, las funciones lambda) y aún tener la garantía de que mi código se compilará en 10 años en un compilador que se ajuste adecuadamente a C ++ 0x cuando es lanzado oficialmente?
Supongo que estoy preguntando si hay alguna posibilidad de que VC ++ 2010 o GCC terminen como VC ++ 6; se publicó antes de que el idioma se estandarizara oficialmente y, por lo tanto, se permitía compilar el código mal formado.
Después de todo, Microsoft dice que "10 es el nuevo 6". ;)
El conjunto de características de C ++ 0X ya está bastante arreglado, por lo que diría que vaya por él. El borrador final de la propuesta debe hacerse en agosto según wikipedia.
De todos modos, muchas de las cosas están disponibles desde boost (en realidad, muchas cosas 0X provienen de boost) - vea boost TR1 . Puede reutilizar esas características a través de boost incluso si el compilador no es totalmente C ++ 0X.
Hay varios elementos que ya he descubierto que no están escritos en el estándar. Por ejemplo, esto no funcionaría:
struct test {
int operator()(int);
};
std::cout << typeid( std::result_of<test(int)>::type ).name() << std::endl;
De acuerdo con el sitio de wikipedia en C ++ 0x debería. Aparentemente, VS2010 usa la definición TR1 de result_of, que es diferente de lo que tendrá C ++ 0x (basado en decltype).
Además, esto no funciona:
std::bind<int>([](int i)->int {return i; });
Falla porque la llamada a std :: result_of (bueno, la implementación de la misma) falla porque el tipo lambda no tiene ningún resultado de typedef. Por supuesto, esta es la razón por la que proporciona el tipo de retorno a la llamada de vinculación, pero aparentemente la ignora por alguna razón y continúa buscando por su cuenta. La versión boost de bind funciona como se espera. Por este motivo, seguimos utilizando la versión boost de bind en nuestro proyecto.
Además, si nota en http://blogs.msdn.com/vcblog/archive/2010/04/06/c-0x-core-language-features-in-vc10-the-table.aspx?CommentPosted=true#commentmessage que hay algunos cambios aún por implementar por VS2010 que afectarán las expresiones lambda. No he podido romperlos, pero luego no he usado lambdas anidadas y probablemente nunca lo haré.
También debe tener en cuenta que boost :: shared_ptr y std :: shared_ptr son incompatibles. No es sorprendente, pero debes saber esto si pretendes usar uno u otro ... Recomiendo no ambos y solo nos quedaremos con el impulso.
Tampoco hay declval en VS2010. Aunque es bastante fácil de hacer:
template < typename T > T&& declval();
Ejemplo de uso:
template < typename T >
struct point
{
T x,y;
};
template < typename T1, typename T2 >
point<decltype(declval<T1>() + declval<T2>())> operator + (point<T1> const& lh, point<T2> const& rh)
{
...
}
También notará en la página que vinculé anteriormente que ya he discutido con los miembros del equipo de desarrollo (o la parte de relaciones públicas o lo que sea) que hay un error en el tipo de declive. Hay algo más que el que menciono, así que mostraré ambos:
template < typename T1, typename T2 >
auto operator + (point<T1> const& lh, point<T2> const& rh)
-> point<decltype(lh.x + rh.x)>
{
...
}
point<int> x; point<double> y;
point<double> pt = x + y; // fails, operator + returned point<const double>
void f();
auto ptr = &f;
std::cout << typeid( decltype(*ptr) ).name() << std::endl;
std::cout << typeid( decltype(*&f) ).name() << std::endl; // should output the same thing...outputs void (*)()
También ... de acuerdo con algunos intercambios de correo electrónico sobre decltype y result_of, esto debería funcionar:
std::result_of< decltype(f)() >::type x = f();
Con mi versión casera de std :: result_of que usa decltype esto funcionaría si la expresión decltype (f) () funcionara correctamente. No es asi. Da algún error sobre la función que devuelve una función. Tienes que usar "decltype (& f) ()" para hacer que la expresión funcione.
Entonces, claro ... lo estamos usando. Hay algunos errores y basura sin embargo. Los beneficios superan la espera en mi humilde opinión. Sin embargo, no espere que su código sea estándar cuando salga el estándar y que los futuros compiladores de MS lo rompan.
Mientras esté de acuerdo con que el código no pueda compilarse en un compilador más antiguo, entonces no tiene nada que perder y podría aprovechar las nuevas características.
Muchas de las cosas importantes (es decir, las que normalmente usarías con frecuencia) están prácticamente grabadas en piedra. Creo que el riesgo de escribir código que se convierte en no estándar es extremadamente bajo, especialmente si se adhiere a un subconjunto de las especificaciones implementadas en los compiladores actuales.
Para obtener una buena tabla que muestre el soporte para las funciones, haga here . Las variables auto
personales, las referencias de valor-r, y las lambdas son, en gran medida, las grandes funciones que se deben utilizar y están bien soportadas.
Si espera que su código permanezca intacto durante años y desea que sobreviva a los cambios del compilador sin intervención, le sugiero que se limite a C ++ 98/03.
Sin embargo, la mayoría del código se mantiene a lo largo del tiempo, por lo que no creo que esta sea una consideración tan importante. Recomendaría usar lo que hace que su código sea mejor y planificar algún trabajo cuando actualice los compiladores.