К сожалению, нет чистого способа сделать это, потому что компилятор не может определить тип G
из объявления функции
template<typename G>
std::ostream& operator<<(std::ostream& os, const typename Chromosome<G>::type& chromosome);
Причина в том, что если бы вы специализировали Chromosome
для разных типов, вы могли бы оказаться в ситуации, когда компилятор не мог бы однозначно вывести G
. Например:
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;
};
Теперь, что случилось бы, если бы вы сделали это?
vector<double> v;
cout << v << endl;
Компилятор не может определить, является ли G
double
или int
в этом случае, потому что оба Chromosome<int>
и Chromosome<double>
имеют vector<double>
как их вложенный тип.
Чтобы это исправить, вам придется явно использовать тип vector<G>
в качестве аргумента:
template<typename G>
std::ostream& operator<<(std::ostream& os, const std::vector<G>& chromosome);
К сожалению, лучшего способа сделать это не существует. Это на самом деле не является дефектом языка, так как есть веская причина запретить его, но на самом деле это мешает вам делать то, что вы хотите в этом контексте.