我创建了一个类Chromosome,它最终只是一个带有ostream运算符的vector的包装器,所以我决定改为使用typedef vector。但是,我在使用模板化的ostream运算符时遇到了麻烦......这是最好的方法吗? (我已经看到了一些方法,但没有得到任何工作)
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;
}
目前我得到的错误是:
chromosome.h:19: error: expected unqualified-id before ‘&’ token
chromosome.h:19: error: expected ‘)’ before ‘&’ token
chromosome.h:19: error: expected initializer before ‘&’ token
干杯。
答案 0 :(得分:6)
不幸的是,没有干净的方法来执行此操作,因为编译器无法从函数声明中推断出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);
不幸的是,确实没有更好的方法。这并不是语言中的缺陷,因为有充分的理由禁止它,但实际上它确实阻止你在这种情况下做你想做的事。
答案 1 :(得分:1)
成员typedef type
是一个从属名称:其含义取决于模板参数G
。您需要使用typename
告诉编译器type
命名一个类型:
const typename Chromosome<G>::type&
有关完整说明,请考虑阅读Stack Overflow C ++ FAQ文章Where to put the “template” and “typename” on dependent names。
正如@templatetypedef在评论中提到的那样,虽然这将使代码能够编译,但是它不会“工作”以允许您将std::vector<G>
插入std::ostream
因为{{1}在非弱化的上下文中。
声明重载并获得预期行为的最简单方法是直接使用type
作为参数类型:
std::vector<G>