std::vector 的 Typedef 和 ostream 运算符
题
我创建了一个 Chromosome 类,它最终只是带有 ostream 运算符的向量的包装器,所以我决定改为 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
干杯。
解决方案
不幸的是,没有干净的方法来做到这一点,因为编译器无法推断出类型 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);
不幸的是,确实没有更好的方法来做到这一点。这并不是真正的语言缺陷,因为有充分的理由禁止它,但它实际上阻止您在这种情况下做您想做的事情。
其他提示
成员 typedef type
是一个从属名称:它的含义取决于模板参数 G
. 。你需要使用一个 typename
告诉编译器 type
命名一个类型:
const typename Chromosome<G>::type&
有关完整说明,请考虑阅读 Stack Overflow C++ 常见问题解答文章, 将“template”和“typename”放在从属名称上的位置.
正如 @templatetypedef 在注释中提到的,虽然这将使代码能够编译,但它不会“工作”以允许您插入 std::vector<G>
进入一个 std::ostream
因为 type
处于非推导的上下文中。
声明重载并获得预期行为的最简单方法是使用 std::vector<G>
直接作为参数类型:
template<typename G>
std::ostream& operator<<(std::ostream& os, const std::vector<G>& chromosome)