pushback program geeksforgeeks for define array c++ templates compiler-construction vector lexicographic

c++ - program - Plantilla dentro de la plantilla: por qué ">>>> debe ser`>> ''dentro de una lista de argumentos de plantilla anidada "



vector c++ pushback (7)

Sé que cuando estamos usando una plantilla dentro de otra plantilla, debemos escribirla así:

vector<pair<int,int> > s;

y si lo escribimos sin el espacio en blanco:

vector<pair<int,int>> s;

obtendremos un error:

`>> ''debería ser`>>'' dentro de una lista de argumentos de plantilla anidada

Veo que esto es comprensible, pero no puedo evitar preguntarme, ¿en qué casos esto será realmente ambiguo?


A veces quieres que sea >> . Considerar

boost::array<int, 1024>>2> x;

En C ++ 03 esto analiza correctamente y crea una matriz de tamaño 256 .


C ++ es realmente increíblemente difícil de analizar, mucho más difícil que la mayoría de los otros lenguajes. Es un lenguaje muy consistente, pero se hace tanto trabajo entre tokenizar la entrada y entender el análisis gramatical de la sintaxis, que las cosas que parecen ser simples para un compilador, a menudo NO lo son.

El operador histórico " >> " es un operador. Se "identifica" ya que el archivo fuente está dividido en tokens. Esos tokens luego son "entendidos" en algún contexto durante el análisis gramatical (mucho después de completarse la tokenización).

Si hiciste un análisis gramatical mientras tokenizaste, entonces tienes "ayuda" para ayudar en la distinción de que " >> " debe considerarse como dos cierres de una declaración (o definición) de plantilla. Sin embargo, históricamente, esto no es cómo funcionan los compiladores históricos de C ++. (Los nuevos compiladores hacen más comentarios entre el análisis gramatical y la tokenización, incluido más "look-aheads" para ayudar a resolver estas ambigüedades).

Sí, el nuevo estándar C ++ 0x cambia eso y obliga a los proveedores de compiladores a volver a escribir sus implementaciones para eliminar la ambigüedad de " >> " en su caso. Por lo tanto, nunca será ambiguo en el futuro. Sin embargo, los compiladores de C ++ más antiguos no pueden manejar eso, por lo que se puede considerar una "buena práctica" mantener el código compatible con el espacio entre los caracteres '' > '' por el momento.


Depende del compilador. Visual Studio no exige esto, es decir, ambos funcionan mientras que g ++ produce un error. Creo que esto depende de la implementación del compilador.


En el estándar actual, la tokenización es codiciosa, por lo que >> se procesará como un único token, de la misma manera que a +++ b se analizará como a ++ + b . Esto ha cambiado y el nuevo estándar. Si bien requiere más trabajo de los implementadores del compilador, se consideró que en general lo vale (y algunos compiladores importantes ya lo implementan como una extensión).


Evite este error configurando un dialecto C ++ apropiado. Por ejemplo, con gcc 4.9 el siguiente archivo no compila con g++ :

#include <vector> #include <utility> int main() { using namespace std; vector<pair<int, int>> v; // compile error! return 0; }

Lleguemos al fondo de las cosas:

#include <iostream> int main() { std::cout << __cplusplus << std::endl; return 0; }

Compilado con solo g++ test.cpp este código imprime 199711. Aunque se lanzó gcc 4.9 en 2014, el dialecto predeterminado de C ++ es C ++ 98 con extensiones de GNU. C ++ 98 requiere que escriba vector<pair<int, int> > . Si te gusta el vector<pair<int, int>> compila más con -std=c++11 o -std=gnu++11 .


Nunca será ambiguo. Esto se demuestra por el hecho de que en C ++ 0x no es necesario escribir un espacio entre el cierre de la plantilla > s.

El problema es que los compiladores preferirían tokenizar la entrada como contexto de la manera más independiente posible. Como C ++ no es un lenguaje independiente del contexto de todos modos, agregar solo este caso especial no va a hacer las cosas particularmente difíciles.


Tuve este problema programando una clase en C ++, y lo resolví haciendo lo siguiente:

Línea que produjo el mismo error mencionado aquí antes:

findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector<std::vector<cv::Point»&);

Línea que pasó a través de GCC Cross Compiler y Worked:

findAndDrawContoursFrame(cv::Mat&,cv::Mat&,std::vector< std::vector<cv::Point> >&);

Para mí fue solo un error en la interpretación de la declaración.