假设最初我使用 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
在这个设计中,有一个Generator
CRTP 类模板,它使用其派生类的 befriended 对 执行复杂计算并在计算的vector<int> v
每个步骤/部分打印结果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
}
这个想法是用户会使用,比如说,并用两个sAggregateOutputter<SimpleDumpOutputter, FancyOutputter
构造对象。每当调用输出器类时,都会遍历s in和类型 in并调用类似.array
ostream
Generator
operator<<
AggregateOutputter
ostream
destinations
Outputters
*dest_iter << *static_cast<Outputter_Iter>(this);
我不确定这将如何工作。我不确定是否可以以这种方式使用多重继承,是否可以在一个array
和一组参数化类型之间“压缩”。有没有人了解这种情况?