很抱歉这个很长的例子,但问题很简单。我正在使用基本访问者模式,使用调解器来管理几个具体的Visitor_pick:public DataVisitor对象。 conrete介体SimulatorMediator用Visitor_pick对象填充列表,然后想要在DataVisitor成员函数上调用std :: thread。我已经尝试了几种变体,使用mem_fun1_t<>等,没有运气。无法编译。什么是正确的语法?
有问题的调用应该在第205行 - 我想将线程附加到v-> visit_SpreadData(一元函数),然后填充threadVec。任何帮助将不胜感激。
#include <iostream>
#include <ostream>
#include <iterator>
#include <list>
#include <vector>
#include <algorithm>
#include <thread>
class PublishEvent;
class Subscriber
{
public:
virtual void update(const PublishEvent *e) = 0;
~Subscriber() = default;
};
class Publisher
{
public:
void attach(Subscriber*);
void detach(Subscriber*);
void notify(const PublishEvent*);
protected:
std::list<Subscriber*> subscribers_;
};
inline void Publisher::
notify(const PublishEvent *e)
{
for (auto &s : subscribers_)
s->update(e);
}
inline void Publisher::
attach(Subscriber *s)
{
subscribers_.push_back(s);
}
inline void Publisher::
detach(Subscriber *s)
{
// inefficient for large nubmer of susbscribers
subscribers_.remove(s);
}
class Mediator;
class SpreadData;
class DataElement;
class DataVisitor : public Publisher, public Subscriber
{
public:
virtual ~DataVisitor() {}
// visit method
virtual void visit_SpreadData(SpreadData *SD) = 0;
// from Publisher::
void update(const PublishEvent *e) override;
void setMediator(Mediator *m)
{
m_ = m;
}
float get_payload() const
{
return payload_;
}
void set_payload(float p)
{
payload_ = p;
}
virtual void gendata(DataElement*) = 0;
protected:
DataVisitor() {}
private:
Mediator *m_;
float payload_;
};
class DataElement
{
public:
virtual ~DataElement() {};
void Accept(DataVisitor&);
protected:
DataElement() {};
};
void DataElement::Accept(DataVisitor &d)
{
d.gendata(this);
}
class SpreadData : public DataElement
{
public:
typedef std::vector<float> return_data_type;
SpreadData() { initiate(); };
SpreadData(std::string filename) { initiate();};
void printdata() const
{
std::copy(data_.begin(),
data_.end(),
std::ostream_iterator<float>(std::cout, " : "));
std::cout << std::endl;
}
return_data_type getdata() const
{
return data_;
}
private:
void initiate()
{
for(int i=0;i<100;i++)
data_.push_back(static_cast<float>(i));
}
return_data_type data_;
};
void DataVisitor::update(const PublishEvent *e)
{
// implementation details
};
template<int N>
class Visitor_pick : public DataVisitor
{
public:
Visitor_pick()
{set_payload(0.); }
// from DataVisitor
void visit_SpreadData(SpreadData*) override;
// from DataVisitor
void gendata(DataElement*);
};
template<int N>
void Visitor_pick<N>::visit_SpreadData(SpreadData *SD)
{
SD->Accept(*this);
}
template<int N>
void Visitor_pick<N>::gendata(DataElement *d)
{
// implementation details
SpreadData *SD = dynamic_cast<SpreadData*>(d);
SpreadData::return_data_type r = SD->getdata();
set_payload(r[N]);
}
class Mediator
{
public:
virtual ~Mediator() = default;
virtual void mediate(DataElement*) = 0;
protected:
Mediator() = default;
virtual void CreateVisitors() = 0;
std::list<DataVisitor*> visitors_;
};
class Mediator_1 : public Mediator
{
public:
Mediator_1()
{
CreateVisitors();
}
void mediate(DataElement*);
private:
void CreateVisitors();
};
void Mediator_1::CreateVisitors()
{
visitors_.push_back(new Visitor_pick<37>());
visitors_.push_back(new Visitor_pick<42>());
visitors_.push_back(new Visitor_pick<47>());
visitors_.push_back(new Visitor_pick<52>());
visitors_.push_back(new Visitor_pick<57>());
}
void Mediator_1::mediate(DataElement *SD)
{
typedef std::mem_fun1_t<void,DataVisitor,SpreadData*> Visitor_fn;
std::cout << "Mediating hard..." << std::endl;
std::vector<std::thread> threadVec;
for(auto &v : visitors_)
{
// Use Visitor_fn to spawn thread on
// unary function v->visit_SpreadData,
// place at back of threadVec
}
for_each(threadVec.begin(), threadVec.end(),
std::mem_fn(&std::thread::join));
for(auto &v : visitors_)
std::cout << "Payload: " << v->get_payload() << std::endl;
}
int main(int argc, char **argv)
{
SpreadData *SD = new SpreadData();
Mediator_1 *M = new Mediator_1();
M->mediate(SD);
delete SD;
delete M;
return 0;
}