teclado resolucion puedo pantalla online imagen desde con cambiar 1920x1080 c++ auto c++14 return-type-deduction

c++ - resolucion - ¿Por qué el tipo de retorno automático cambia la resolución de sobrecarga?



cambiar resolucion de pantalla windows 8 (1)

Basta con mirar esta llamada:

d.fun(foo_t{});

Usted crea un temporal (es decir, rvalue), pasándolo como argumento a la función. Ahora, ¿qué crees que sucede?

  • Primero intenta enlazar con el argumento Arg&& , ya que puede aceptar rvalue pero debido a una deducción de tipo de retorno no válida ( que de nuevo debido a foo_t no se puede convertir en unsigned int , debido a que b.fun(std::forward<Args>(args)...) resulta ser una expresión no válida ), esta función se rechaza si utiliza decltype(expr) como tipo de retorno, ya que en este caso SFINAE aparece en la imagen. Pero si usa simplemente auto , SFINAE no aparece en la imagen y el error se clasifica como un error grave que da como resultado un error de compilación.

  • La segunda sobrecarga que acepta el foo_t const& as se llama si SFINAE funciona en el primer caso.

Gracias a decltype como tipo de retorno, C ++ 11 hizo que introducir decoradores fuera extremadamente fácil. Por ejemplo, considere esta clase:

struct base { void fun(unsigned) {} };

Quiero decorarlo con características adicionales, y como lo haré varias veces con diferentes tipos de decoraciones, primero presento una clase de decorator que simplemente envía todo a la base . En el código real, esto se hace a través de std::shared_ptr para que pueda eliminar las decoraciones y recuperar el objeto "desnudo", y todo está templado.

#include <utility> // std::forward struct decorator { base b; template <typename... Args> auto fun(Args&&... args) -> decltype(b.fun(std::forward<Args>(args)...)) { return b.fun(std::forward<Args>(args)...); } };

Perfecto reenvío y decltype son simplemente maravillosos. En el código real, en realidad uso una macro que solo necesita el nombre de la función, todo lo demás es repetitivo.

Y luego, puedo introducir una clase derived que agrega características a mi objeto ( derived es impropia, de acuerdo, pero ayuda a entender que derived es un tipo de base , aunque no por herencia).

struct foo_t {}; struct derived : decorator { using decorator::fun; // I want "native" fun, and decorated fun. void fun(const foo_t&) {} }; int main() { derived d; d.fun(foo_t{}); }

Luego vino C ++ 14, con devolución de tipo de deducción, que permite escribir cosas de una manera más simple: eliminar la parte de tipo decltype de la función de reenvío:

struct decorator { base b; template <typename... Args> auto fun(Args&&... args) { return b.fun(std::forward<Args>(args)...); } };

Y luego se rompe. Sí, al menos según GCC y Clang, esto:

template <typename... Args> auto fun(Args&&... args) -> decltype(b.fun(std::forward<Args>(args)...)) { return b.fun(std::forward<Args>(args)...); } };

no es equivalente a esto (y el problema no es auto vs. decltype(auto) ):

template <typename... Args> auto fun(Args&&... args) { return b.fun(std::forward<Args>(args)...); } };

La resolución de sobrecarga parece ser completamente diferente y termina así:

clang++-mp-3.5 -std=c++1y main.cc main.cc:19:18: error: no viable conversion from ''foo_t'' to ''unsigned int'' return b.fun(std::forward<Args>(args)...); ^~~~~~~~~~~~~~~~~~~~~~~~ main.cc:32:5: note: in instantiation of function template specialization ''decorator::fun<foo_t>'' requested here d.fun(foo_t{}); ^ main.cc:7:20: note: passing argument to parameter here void fun(unsigned) {} ^

Entiendo el error: mi llamada ( d.fun(foo_t{}) ) no coincide perfectamente con la firma de const foo_t& derived::fun , que requiere una const foo_t& , por lo que el muy ansioso decorator::fun entra en acción (sabemos cómo Args&&... es extremadamente impaciente por unirse a cualquier cosa que no coincida perfectamente). Así que reenvía esto a la base::fun que no puede manejar foo_t .

Si cambio derived::fun para tomar foo_t lugar de const foo_t& , entonces funciona como se esperaba, lo que demuestra que de hecho aquí el problema es que hay una competencia entre derived::fun y decorator::fun .

Sin embargo, ¿por qué diablos se muestra esto con una deducción de tipo de retorno? Y más precisamente, ¿ por qué fue elegido este comportamiento por el comité?

Para hacer las cosas más fáciles, en Coliru:

¡Gracias!