Pregunta

He creado una clase Cromosoma, que terminó por ser simplemente un contenedor para que el vector con un ostream operador, así que me he decidido a typedef vector lugar.Sin embargo, estoy teniendo problemas con la plantilla ostream operador...Es esta la mejor manera de ir sobre ella?(Yo he visto un par de enfoques y han fallado en obtener cualquier trabajo)

template<typename G>
class Chromosome {
 public:
  typedef typename std::vector<G> type;
  typedef typename std::pair<type *,type *> ptr_pair;
};

template<typename G> //line 19 below:
std::ostream& operator<<(std::ostream& os, const Chromosome<G>::type& chromosome) {
  for(auto iter = chromosome.begin(); iter != chromosome.end(); ++iter)
    std::cout << *iter;
  return os;
}

En el momento en que el error que voy es:

chromosome.h:19: error: expected unqualified-id before ‘&’ token
chromosome.h:19: error: expected ‘)’ before ‘&’ token
chromosome.h:19: error: expected initializer before ‘&’ token

Saludos.

¿Fue útil?

Solución

Desafortunadamente, no hay una manera correcta de hacer esto porque el compilador no puede deducir el tipo de G a partir de la declaración de la función

template<typename G>
std::ostream& operator<<(std::ostream& os, const typename Chromosome<G>::type& chromosome);

La razón es que si se especializan Chromosome para los diferentes tipos, usted podría terminar en una situación en la que el compilador no podía inferir inequívocamente G.Por ejemplo:

template <typename G> class Chromosome {
public:
    typedef std::vector<G> type; // No typename needed here, BTW
};

template <> class Chromosome<int> {
public:
    typedef std::vector<double> type;
};

Ahora, ¿qué pasaría si usted hizo esto?

vector<double> v;
cout << v << endl;

El compilador no puede saber si G es double o int en este caso, debido a que ambos Chromosome<int> y Chromosome<double> han vector<double> como su tipo anidado.

Para solucionar esto, usted tendrá que utilizar explícitamente el tipo de vector<G> como el argumento:

template<typename G>
std::ostream& operator<<(std::ostream& os, const std::vector<G>& chromosome);

Por desgracia, en realidad no hay una mejor manera de hacer esto.No es realmente un defecto en el lenguaje, ya que hay una buena razón para prohibir, pero en realidad le impide hacer lo que quieres en este contexto.

Otros consejos

El miembro typedef type es un dependiente de nombre de:su significado depende del parámetro de plantilla G.Usted necesidad de utilizar un typename para indicar al compilador que type los nombres de un tipo:

const typename Chromosome<G>::type&

Para la explicación completa, considere la posibilidad de leer el Desbordamiento de Pila en C++ FAQ artículo, Donde poner la "plantilla" y "typename" en dependiente de los nombres de.

Como @templatetypedef alude a ello en los comentarios, mientras que esto permitirá que el código se compile, no "trabajo" que le permiten insertar un std::vector<G> en un std::ostream porque type es en un nondeduced contexto.

La forma más sencilla de declarar la sobrecarga y obtener el comportamiento esperado es el uso de std::vector<G> directamente como el tipo de argumento:

template<typename G>
std::ostream& operator<<(std::ostream& os, const std::vector<G>& chromosome)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top