[英]Typedef and ostream operator for a std::vector
I created a class Chromosome that ended up simply being a wrapper for vector with an ostream operator, so I've decided to typedef vector instead. 我创建了一个Chromosome类,最终只是用ostream运算符对vector进行了包装,因此我决定改用typedef vector。 However, I'm having trouble with the templated ostream operator... Is this the best way to go about it?
但是,我在使用模板化的ostream运算符时遇到了麻烦...这是最好的方法吗? (I've seen a few approaches and have failed to get any to work)
(我已经看到了一些方法,但没有任何效果)
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;
}
At the moment the error I'm getting is: 目前,我得到的错误是:
chromosome.h:19: error: expected unqualified-id before ‘&’ token
chromosome.h:19: error: expected ‘)’ before ‘&’ token
chromosome.h:19: error: expected initializer before ‘&’ token
Cheers. 干杯。
Unfortunately, there's no clean way to do this because the compiler can't deduce the type of G
from the function declaration 不幸的是,没有干净的方法可以做到这一点,因为编译器无法从函数声明中推断出
G
的类型。
template<typename G>
std::ostream& operator<<(std::ostream& os, const typename Chromosome<G>::type& chromosome);
The reason is that if you were to specialize Chromosome
for different types, you could end up in a situation where the compiler couldn't unambiguously infer G
. 原因是,如果要专门针对不同类型的
Chromosome
,则可能会遇到编译器无法明确推断G
。 For example: 例如:
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;
};
Now, what would happen if you did this? 现在,如果您这样做,会发生什么?
vector<double> v;
cout << v << endl;
The compiler can't tell if G
is double
or int
in this case, because both Chromosome<int>
and Chromosome<double>
have vector<double>
as their nested type. 在这种情况下,编译器无法确定
G
是double
还是int
,因为Chromosome<int>
和Chromosome<double>
都将vector<double>
作为其嵌套类型。
To fix this, you'll have to explicitly use the type vector<G>
as the argument: 要解决此问题,您必须显式使用
vector<G>
类型作为参数:
template<typename G>
std::ostream& operator<<(std::ostream& os, const std::vector<G>& chromosome);
Unfortunately, there really isn't a better way of doing this. 不幸的是,确实没有更好的方法可以做到这一点。 It's not really a defect in the language, since there's a good reason to prohibit it, but it does actually prevent you from doing what you want to in this context.
这并不是语言的缺陷,因为有充分的理由要禁止它,但这实际上阻止了您在这种情况下做自己想做的事情。
The member typedef type
is a dependent name: its meaning is dependent upon the template parameter G
. 成员typedef
type
是从属名称:其含义取决于模板参数G
You need to use a typename
to tell the compiler that type
names a type: 你需要使用一个
typename
来告诉编译器type
名称的类型:
const typename Chromosome<G>::type&
For the full explanation, consider reading the Stack Overflow C++ FAQ article, Where to put the “template” and “typename” on dependent names . 有关完整的解释,请考虑阅读Stack Overflow C ++常见问题解答文章“将“模板”和“类型名”放在从属名称上的位置) 。
As @templatetypedef alludes to in the comments, while this will enable the code to compile, it won't "work" to allow you to insert an std::vector<G>
into an std::ostream
because type
is in a nondeduced context. 正如@templatetypedef在注释中所暗示的那样,尽管这将使代码能够编译,但它不能“工作”以允许您将
std::vector<G>
插入到std::ostream
因为type
是非推断的上下文。
The easiest way to declare the overload and get the expected behavior is to use std::vector<G>
directly as the argument type: 声明重载并获得预期行为的最简单方法是直接使用
std::vector<G>
作为参数类型:
template<typename G>
std::ostream& operator<<(std::ostream& os, const std::vector<G>& chromosome)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.