template ¿Por qué las plantillas de C++ usan la sintaxis del corchete angular?



use templates c++ (1)

La pregunta titular se refiere a las decisiones de diseño en el estándar de C ++ que introdujeron plantillas alrededor de 1990.

¿Por qué los diseñadores utilizaron <> (corchetes angulares) en lugar de, por ejemplo, () (paréntesis redondos)? Si lo hubiera hecho, habría salvado a muchos programadores del error relacionado con el cambio de bits

std::vector<std::vector<int>> // does not work until C++11

Eso solo se solucionó en C ++ 11. No veo la razón de introducir una sintaxis adicional como esa cuando, posiblemente, los corchetes redondos hubieran servido para el mismo propósito manteniendo los cambios minimalistas. Inste usted podría haber utilizado

template(typename T) // Define template if round brackets could be used
mytemplate { ... }
...
...
mytemplate(mytemplate(int)) obj; //Instantiate template when round brackets could be used

¿Puede alguien bien versado en la historia de C ++ desenterrar los fundamentos del diseño original para usar soportes de ángulo? Alternativamente, ¿puedes mostrar por qué otras soluciones no habrían funcionado tan bien?

https://code.i-harness.com


Bjarne Stroustrup incorporó las plantillas en el documento USENIX Parametrized Types for C ++ de 1988, que luego se incorporó al The Annotated C ++ Reference Manual publicado en 1990 (la versión anterior a C ++ estandarizada). Según el papel,

Los corchetes <…> se usan con preferencia a los paréntesis (…) parte para enfatizar la naturaleza diferente de los argumentos de la plantilla (se evaluarán en el momento de la compilación) y en parte porque los paréntesis ya están excesivamente usados ​​en C ++ .

...

9.2. <…> Vs (…)

Pero ¿por qué usar paréntesis en lugar de paréntesis? Como se mencionó anteriormente, los paréntesis ya tienen muchos usos en C ++. Una pista sintáctica (los corchetes <…> ) puede ser útil para recordarle al usuario la diferente naturaleza de los parámetros de tipo (se evalúan en tiempo de compilación) . Además, el uso de paréntesis podría llevar a un código bastante oscuro:

template(int sz = 20) class buffer {
    buffer(int i = 10);
    // ...
};
buffer b1(100)(200);
buffer b2(100);      // b2(100)(10) or b2(20)(100)?
buffer b3;           // legal?

Estos problemas se convertirían en una seria preocupación práctica si se adoptara la notación para la desambiguación explícita de llamadas a funciones sobrecargadas. La alternativa elegida parece mucho más limpia:

template<int sz = 20> class buffer {
    buffer(sz)(int i = 10);
    // ...
};
buffer b1<100>(200);
buffer b2<100>;      // b2<100>(10)
buffer b3;           // b3<20>(10)
buffer b4(100);      // b4<20>(100)

El documento también explica por qué se utilizan las palabras clave de template y class .

Tenga en cuenta que Stroustrup colocó el <…> después del nombre de la variable de la misma manera que int x[10] para argumentar en contra (…) , aunque esta ubicación nunca se usa en ninguna otra parte del documento.

Sin embargo, su argumento de que "usar (…) puede llevar a un código oscuro / ambiguo" sigue siendo válido. Como se mencionó en el comentario de esta pregunta, el uso del paréntesis T(x) conduce a la ambigüedad con el tipo de función o la llamada de función (tenga en cuenta que T puede ser una plantilla de función y que los valores permitidos de C ++ son argumentos de plantilla).

De manera similar, el uso de corchetes T[x] conduce a la ambigüedad con el tipo de matriz o la indexación.

No veo por qué T{x} no se puede usar todavía, tal vez simplemente no se consideró, o tal vez es demasiado feo para que {…} use en todas partes.





template-meta-programming