Pregunta

Tengo un problema realmente desagradable con algún código que he escrito. Encontré a alguien más que tenía el mismo problema en stackoverflow y probé las soluciones, pero ninguna funcionó para mí.

Escribo varios tipos de STL comunes que estoy usando y ninguno de los otros tiene ningún problema, excepto cuando intento escribir un mapa. Me sale un & Quot; algún_archivo.h: 83: error: inicializador esperado antes de '& Lt;' token " error al incluir mi encabezado en un programa de prueba.

Aquí está la parte importante del encabezado (some_file.h):

#ifndef SOME_FILE_H
#define SOME_FILE_H
// some syntax-correct enums+class prototypes
typedef std::string str;
typedef std::vector<Column> col_vec;
typedef col_vec::iterator col_vec_i;
typedef std::vector<Row> row_vec;
typedef row_vec::iterator row_vec_i;
typedef std::vector<str> str_vec;
typedef str_vec::iterator str_vec_i;
typedef std::vector<Object> obj_vec;
typedef obj_vec::iterator obj_vec_i;
typedef std::map<Column, Object> col_obj_map; // error occurs on this line
typedef std::pair<Column, Object> col_obj_pair;

Las inclusiones en some_file.cpp son:

#include <utility>
#include <map>
#include <vector>
#include <iostream>
#include <string>
#include <stdio.h>
#include <cc++/file.h>
#include "some_file.h"

El archivo de prueba simplemente incluye una cadena, un vector y mi archivo en ese orden. Tiene un método principal que simplemente hace una especie de hola mundo.

Lo curioso es que rápidamente reuní una clase con plantilla para ver dónde estaba el problema (reemplazando " std::map<Column... " con " hello<Column... " ;) y funcionó sin problemas.

Ya he creado la sobrecarga del operador requerida por el mapa si está utilizando una clase sin un operador '<'.

¿Fue útil?

Solución

Tiene este problema porque el compilador no sabe qué es un mapa. No se sabe porque el encabezado del mapa aún no se ha incluido. Su encabezado utiliza las plantillas STL: cadena, vector, mapa, & Amp; par. Sin embargo, no los define, ni tiene ninguna referencia a dónde están definidos. La razón por la cual su archivo de prueba aparece en el mapa y no en la cadena o el vector es que incluye la cadena y los encabezados de los vectores antes de some_file.h para que la cadena y el vector estén definidos, pero el mapa no. Si incluye el encabezado del mapa, funcionará, pero luego puede quejarse del par (a menos que su implementación STL particular incluya el par en el encabezado del mapa).

Generalmente, la mejor política es incluir el encabezado estándar adecuado para cada tipo que use en su propio encabezado. Entonces some_file.h debería tener, al menos, estos encabezados:

#include <string>
#include <map>
#include <utility> // header for pair
#include <vector>

La desventaja de este enfoque es que el preprocesador tiene que cargar cada archivo cada vez y pasar por el #ifdef ... #endif procesamiento de inclusión condicional, por lo que si tiene miles de archivos y docenas de inclusiones en cada archivo, esto podría aumentar significativamente el tiempo de compilación. Sin embargo, en la mayoría de los proyectos, la molestia adicional de tener que administrar la inclusión del encabezado manualmente no vale la ganancia minúscula en el tiempo de compilación. Es por eso que el libro de Scott Meyers STL efectivo tiene & Quot; Siempre # incluir los encabezados adecuados " como item # 48 .

Otros consejos

¿Hay un #include <map> en algún lugar de su archivo de encabezado?

Pon eso ahí para al menos ver si funciona. Deberías estar haciendo eso de todos modos.

Debería cambiar algunas de esas inclusiones en su archivo de encabezado. Estos deben colocarse antes de sus declaraciones typedef.

es decir

#include <map>
#include <string>
#include <map>

De lo contrario, cualquier otra cosa, incluido some_file.h (como su programa principal) no sabrá lo que son a menos que también coloque estos incluye antes de #include " some_file.h " incluya la directiva en su archivo fuente principal del programa. Si haces esto, el problema debería desaparecer.

Como varias personas han señalado, el compilador no encuentra la definición de mapa. Como parece que incluye el encabezado del mapa, hay otras 2 causas posibles que se me ocurren:

  1. Se está cargando otro archivo de encabezado llamado mapa en lugar del encabezado del mapa estándar. Creo que esto es poco probable.
  2. Otro encabezado es # definiendo el mapa como algo más.

Una forma de verificar cualquiera de ellos es hacer que su compilador genere el archivo postprocesado, es decir, el archivo fuente después de que se haya ejecutado a través del preprocesador C pero antes de que se haya compilado. Entonces debería poder encontrar su línea ofensiva y ver si el tipo de mapa ha sido reemplazado por otra cosa. También debería poder buscar una copia de seguridad del archivo y ver en qué encabezado se ocultó el #include.

La forma en que genera el archivo postprocesado depende del compilador: compruebe los indicadores de línea cmd en los documentos de su compilador.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top