让我们假设原来我有使用CRTP了如下设计:如何将CRTP与可变模板一起使用?
template<class Outputter> class Generator {
protected:
vector<int> v;
private:
void work(ostream& out) {
// perform first part of some complex operations on v
out << *static_cast<Outputter *>(this);
// perform second part of some complex operations on v
out << *static_cast<Outputter *>(this);
// many more ....
// perform some final actions
}
public:
Generator(unsigned length): v(length) {}
friend ostream& operator<<(ostream& out, Outputter&& generator) {
// perform some preparation work
work(out);
// perform some final actions
return out;
}
};
class SimpleDumpOutputter : public Generator<SimpleDumpOutputter> {
private:
unsigned count;
public:
SimpleDumpOutputter(unsigned length): Generator(length), count() {}
friend ostream& operator<<(ostream& out, SimpleDumpOutputter& outputter) {
out << "Step " << ++count << " of calculation: "
copy(outputter.v.begin(), outputter.v.end(), ostream_iterator<int>(out, " "));
out << endl;
return out;
}
};
class FancyOutputter : public Generator<FancyOutputter> { // create a graph using graphviz's dot language to visualise v
private:
// abbreviated
public:
FancyOutputter(unsigned length): Generator(length) {}
friend ostream& operator<<(ostream& out, FancyOutputter& outputter) {
// write statements to out
return out;
}
};
// some more different Outputters, for example an Outputter that creates a pretty LaTeX document
在这种设计中,是在vector<int> v
执行复杂的计算和打印结果在每一步一个Generator
CRTP类模板/计算的一部分使用其派生类朋友operator<<
。
这是我想要实现的一个有趣的概念:我想在一次执行中以多种格式输出。具体而言,我认为我可以这样做:
template<class Outputters> class AggregateOutputter : public Generator<AggregateOutputter<Outputters...> > {
private:
static const unsigned outputter_count = sizeof...(Outputters);
typedef array<ostream *, outputter_count> DestArr;
DestArr destinations;
public:
AggregateOutputter(unsigned v_length, DestArr destinations): IsomerGenerator<AggregateOutputter<Outputters...> >(length), destinations(destinations) {}
friend ostream& operator<<(ostream&, AggregateOutputter& outputter); // first argument is dummy, because we would use the ostreams in destinations
}
的想法是,用户会用,说,AggregateOutputter<SimpleDumpOutputter, FancyOutputter
和构建具有两个ostream
秒的array
的对象。每当Generator
在输出器类上调用operator<<
时,AggregateOutputter
将遍历destinations
中的ostream
和Outputters
中的类型,并调用沿着*dest_iter << *static_cast<Outputter_Iter>(this);
的行的东西。
我不知道这将如何工作。我不确定是否可以以这种方式使用多重继承,是否可以在一个array
和一组参数化类型之间“拉链”。有没有人知道这种情况?
在您的原始版本中,您的'operator <<'重载是'friend's,但正在使用'this'。这不会编译 – 2013-04-06 19:27:22
@AndyProwl我很抱歉。我试图简化产品代码,但犯了一个错误。实际上'operator <<'调用私有成员函数'work'来完成实际工作。 – kccqzy 2013-04-06 19:32:32
您可以使用称为索引的东西来压缩数组和类型列表。 – Pubby 2013-04-06 19:36:11