sintaxis - ¿Cómo se puede usar Boost para lograr los tipos de devolución automática de estilo C++ 14?
sintaxis de c++ (2)
El único tipo de retorno de función deducida posible en C ++ 11 es el tipo de retorno de una lambda. C ++ 11 restringe el uso de lambdas, sin embargo. Esto funciona:
auto add = [](int a, int b) { return a + b; };
Esto es válido y define add
como un lambda que define una función de miembro operator()
que devuelve int
. Como la lambda no captura nada, incluso puedes escribir
auto add = +[](int a, int b) { return a + b; };
para hacer add
un puntero-a-función regular: obtiene el tipo int(*)(int, int)
.
Sin embargo, C ++ 11 no permite que los tipos de parámetros se especifiquen como auto
, ni que el add
se defina como una variable de plantilla, por lo que no puede usar esto para deducir genéricamente un tipo de devolución. Un intento de finalizarlo en una clase de plantilla falla:
template <typename A, typename B>
struct S { static auto add = [](A a, B b) { return a + b; }; }; // invalid
No es válido inicializar add
en clase aquí, y no puede usar el auto
menos que el miembro se inicialice en la clase. Además, incluso si funcionó, no permitiría la deducción de A
o B
, que parece ser más de lo que estás buscando.
Dadas esas limitaciones, no veo otra alternativa que repetir la expresión. Sin embargo, podrías ocultar la repetición en una macro trivial.
#define AUTO_RETURN(func, ...) auto func -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
template <typename A, typename B>
AUTO_RETURN(add(A a, B b), a + b)
O la variante apuntada por Marc Glisse,
#define RETURNS(...) noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
template <typename A, typename B>
auto add(A a, B b) RETURNS(a + b)
que se ve un poco más limpio.
Puede que ya haya algo como esto en Boost, no sé. De todos modos, dada la trivialidad, Boost parece excesivo aquí.
Supongamos que tengo una función que agrega dos valores juntos. Si no sé nada sobre los tipos, básicamente tengo que escribir mi función dos veces; una vez en el valor de retorno real y otra vez como el especificador de tipo de devolución:
template <typename A, typename B>
auto Add(const A& a, const B& b) ->std::decay<decltype(a + b)>::type
{
return a + b;
}
Mientras esto funciona, es indeseable porque es difícil de leer y difícil de mantener.
En C ++ 14 esto no será un problema, porque podemos descartar el especificador de tipo de retorno (no estoy seguro de que vaya a hacer la descomposición ...). Por ahora, estoy atrapado con C ++ 11.
Según mi experiencia, cada vez que busco una característica en C ++ que todavía no haya llegado al estándar, pero para la cual existe una necesidad obvia, la biblioteca de Boost generalmente tiene una solución. He buscado en la documentación, pero no he encontrado nada que pueda ayudarme. Las características BOOST_AUTO_RETURN
y BOOST_TYPEOF_TPL
parecen más dirigidas a proporcionar la funcionalidad C ++ 11 a los usuarios de C ++ 03.
Básicamente, lo que busco es algo que tenga la siguiente funcionalidad:
template <typename A, typename B>
auto Add(const A& a, const B& b)
{
return a + b; // Deduce return type from this, like C++14 would
}
¿Hay alguna funcionalidad en la biblioteca de Boost que desconozco (o un ingenioso truco en C ++ 11) que me permita renunciar al explícito -> decltype(...)
después de cada tipo de retorno automático? ¿Cómo se implementaría esto?