entre - c++20
La deducción de argumentos de la plantilla de clase no funciona con la plantilla de alias (2)
De http://en.cppreference.com/w/cpp/language/template_argument_deduction , "las plantillas de alias nunca se deducen". Por lo tanto, es por diseño.
Considere el código pegado a continuación. He definido una clase muy simple, para la cual el compilador genera una guía de deducción implícita para que pueda construirse sin argumentos de plantilla explícitos. Sin embargo, la deducción de argumentos de la plantilla no funciona para construir un objeto a partir de una plantilla de alias simple que solo reenvía directamente a la clase de destino:
template< typename A, typename B >
struct Foo {
Foo( A const &a, B const &b )
: a_(a), b_(b)
{ }
A a_;
B b_;
};
template< typename A, typename B >
using Bar = Foo<A, B>;
auto foobar() {
Foo r{1, 2};
Bar s{3, 4};
// ../src/geo/vector_test_unit.cpp: In function ''auto foobar()'':
// ../src/geo/vector_test_unit.cpp:16:6: error: missing template arguments before ''s''
// Bar s{3, 4};
// ^
return 1;
}
Como puede ver en un comentario de código anterior, g ++ me está dando un error sobre el uso de la plantilla con alias sin argumentos de plantilla. Esperaba en tal caso que se reenviaría la deducción de argumentos de plantilla.
Entonces, mi pregunta : ¿Es esto mediante un diseño expreso de la redacción actual de la propuesta de deducción de argumentos de plantilla de clase? ¿O es esta una característica o error sin terminar en la implementación actual de g ++ de la característica? Y esto sería más una pregunta para los autores de la propuesta, o para el Comité C ++ ISO, pero si alguno de ellos ve esto: ¿Desearía que la redacción final de la característica incluyera también habilitar plantillas de alias como esta? ¿Se han generado guías implícitas para ellos?
Puedo entender que dado que las plantillas de alias pueden tener cualquier tipo de parámetros de plantilla, no siempre es posible que el compilador deduzca con éxito los argumentos de la plantilla de la clase de destino, pero en un caso como este esperaría que el compilador fuera capaz de hacerlo. de la misma manera que puede directamente para la clase objetivo.
Estoy construyendo con gcc construido desde cabeza hace solo unos días, usando --std=c++1z
. La información completa de la versión es: gcc version 7.0.0 20161201 (experimental) (Homebrew gcc HEAD- --with-jit)
Esta fue una característica que consideramos al formular la propuesta, pero finalmente se eliminó porque aún no teníamos un diseño lo suficientemente bueno para ella. En particular, hay algunas sutilezas con respecto a cómo selecciona y transforma las guías de deducción de la plantilla con alias en guías de deducción para la plantilla de alias. También hay preguntas abiertas sobre cómo comportarse si la plantilla de alias no es un alias simple para otra plantilla. Algunos ejemplos:
template<typename T> struct Q { Q(T); }; // #1
template<typename T> struct Q<T*> { Q(T); }; // #2
template<typename T> using QP = Q<T*>;
int *x;
Q p = x; // deduces Q<int*> using #1, ill-formed
QP q = x; // deduces Q<int*> using #1, or
// deduces Q<int**> using #2?
template<typename T> Q(T) -> Q<T>; // #3
QP r = x; // can we use deduction guide #3 here?
template<typename T> Q(T*) -> Q<T**>; // #4
int **y;
QP s = y; // can we use deduction guide #4 here?
template<typename T> struct A { typedef T type; struct Y {}; };
template<typename T> using X = typename A<T>::type;
template<typename T> using Y = typename A<T>::Y;
X x = 4; // can this deduce T == int?
Y y = A<int>::Y(); // can this deduce T == int?
Hay respuestas decentes a las preguntas anteriores, pero abordarlas agrega complejidad, y parece preferible no permitir la deducción de plantillas de alias para C ++ 17 en lugar de apresurar algo defectuoso.
Predigo que veremos un artículo de Faisal que propone esta característica para C ++ 20.