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
干杯。
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. However, I'm having trouble with the templated ostream operator... Is this the best way to go about it? (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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不幸的是,没有干净的方法来做到这一点,因为编译器无法从函数声明中推断出
G
的类型。原因是,如果您要针对不同的情况专门化
Chromosome
类型,您最终可能会遇到编译器无法明确推断G
的情况。例如:现在,如果你这样做会发生什么?
在这种情况下,编译器无法判断
G
是double
还是int
,因为Chromosome
和Chromosome
将vector
作为其嵌套类型。要解决此问题,您必须显式使用
vector
类型作为参数:不幸的是,确实没有更好的方法来做到这一点。这并不是真正的语言缺陷,因为有充分的理由禁止它,但它实际上阻止您在这种情况下做您想做的事情。
Unfortunately, there's no clean way to do this because the compiler can't deduce the type of
G
from the function declarationThe 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 inferG
. For example:Now, what would happen if you did this?
The compiler can't tell if
G
isdouble
orint
in this case, because bothChromosome<int>
andChromosome<double>
havevector<double>
as their nested type.To fix this, you'll have to explicitly use the type
vector<G>
as the argument: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.
成员 typedef
type
是一个从属名称:其含义取决于模板参数G
。您需要使用typename
告诉编译器type
命名了一个类型:有关完整说明,请考虑阅读 Stack Overflow C++ 常见问题解答文章 将“template”和“typename”放在依赖名称上的位置 。
正如 @templatetypedef 在注释中提到的,虽然这将使代码能够编译,但它不会“工作”以允许您将
std::vector
插入std::ostream
因为type
处于非推导上下文中。声明重载并获得预期行为的最简单方法是直接使用 std::vector作为参数类型:
The member typedef
type
is a dependent name: its meaning is dependent upon the template parameterG
. You need to use atypename
to tell the compiler thattype
names a type:For the full explanation, consider reading the Stack Overflow C++ FAQ article, Where to put the “template” and “typename” on dependent names.
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 anstd::ostream
becausetype
is in a nondeduced context.The easiest way to declare the overload and get the expected behavior is to use
std::vector<G>
directly as the argument type: