C++ 尝试学习BOOST::ANY Q1
这个程序在通话中自动识别故障C++ 尝试学习BOOST::ANY Q1,c++,boost-any,C++,Boost Any,这个程序在通话中自动识别故障 p->Change(1999); 当我在调试器中运行它时,似乎我进入了Change函数,但是在检查时,这个指针是0x00。很明显,我使用BOOST::any时有误,但我不确定我做错了什么 我相信下面的汽车的返回类型 //pressure type = Pressure<Printer, Printer> auto pressure = MakeSubject<Pressure>(
p->Change(1999);
当我在调试器中运行它时,似乎我进入了Change函数,但是在检查时,这个指针是0x00。很明显,我使用BOOST::any时有误,但我不确定我做错了什么
我相信下面的汽车的返回类型
//pressure type = Pressure<Printer, Printer>
auto pressure = MakeSubject<Pressure>(
BindObservers(printerObs1, printerObs2), initialPressure);
//压力类型=压力
自动压力=MakeSubject(
binderobserver(printerObs1、printerObs2),初始压力;
我可能需要将decltype和auto与Boost::any一起使用
boost::any_cast<Pressure<Printer>> // change Pressure<Printer> to use decltype<pressure> ?
boost::有没有改变压力以使用decltype?
但这扩展了我对正在发生的事情的理解
// static_observer header file
#include <utility>
#include <tuple>
#include <iostream>
enum class EventType {UNKNOWN};
// Note: All Observers must implement OnNotify for any subject types they wish to observe
// Any unimplemented subject types that are used will result in a compiler error
template <typename Base> class Observer
{
public:
Observer() : obsID_(obsIDTracker_++) {}
template <typename T> void OnNotifyImpl(T &subject, EventType event)
{
static_cast<Base *>(this)->OnNotify(subject, event);
}
int GetID() const
{
return obsID_;
}
private:
int obsID_;
static int obsIDTracker_;
};
template <typename base> int Observer<base>::obsIDTracker_ = 0;
// Recursive helper structs for implementing calls to all observers held within subjects
template <int N, typename T, typename... Args> struct NotifyHelper
{
static void NotifyImpl(T &subject, EventType event,
std::tuple<Args...> &obs)
{
std::get<sizeof...(Args) - N>(obs).OnNotifyImpl(subject, event);
NotifyHelper<N - 1, T, Args...>::NotifyImpl(subject, event, obs);
}
};
template <typename T, typename... Args> struct NotifyHelper<0, T, Args...>
{
static void NotifyImpl(T &subject, EventType event,
std::tuple<Args...> &obs) {}
};
// See MakeSubject function for instance usage
template <typename T, typename... Obs> class Subject
{
public:
static const int NumberOfObservers = sizeof...(Obs);
Subject(std::tuple<Obs &...> &&obs) : observers(obs) {}
void NotifyAll(EventType event)
{
NotifyHelper<NumberOfObservers, T, Obs &...>::NotifyImpl(
*static_cast<T *>(this), event, observers);
}
private:
std::tuple<Obs &...> observers;
};
// CRTP Abstract Base class for implementing static subject.
// Example Subclass Usage -- Pressure Sensor:
template <typename... Obs>
class Pressure : public Subject<Pressure<Obs...>, Obs...>
{
public:
typedef Subject<Pressure<Obs...>, Obs...> BaseType;
Pressure(std::tuple<Obs &...> &&observers, int pressure)
: BaseType(std::move(observers)), pressure_(pressure) {}
void Change(int value)
{
pressure_ = value;
this->NotifyAll(EventType::UNKNOWN);
}
int GetPressure() const
{
return pressure_;
}
private:
int pressure_;
};
// CRTP Abstract Base class for implementing static subject.
// Example Subclass Usage -- Printing Observer:
class Printer : public Observer<Printer>
{
public:
Printer() : timesTriggered_(0) {}
template <typename... Args>
void OnNotify(Pressure<Args...> &subject, EventType event)
{
std::cout << "Observer ID: " << this->GetID() << std::endl;
switch (event)
{
case EventType::UNKNOWN:
{
std::cout << "Unknown Event -- Event #" << timesTriggered_++
<< std::endl;
std::cout << "Pressure: " << subject.GetPressure() << std::endl;
break;
}
default:
{
break;
}
}
}
private:
int timesTriggered_;
};
// Binding function for use with MakeSubject
// Arguments: observer objects to observe subject notifications
// Return: tuple of references to observers
template <typename... Obs> std::tuple<Obs &...> BindObservers(Obs &... obs)
{
return std::tuple<Obs &...>(obs...);
}
// Creator to ease subject creation
// Template Arguments: Subject subclass type
// Arguments: Result from BindObservers
// Any constructor arguments for Subject subclass
// Return: Subject subclass
// Example Usage:
// auto pressure = MakeSubject<Pressure>(BindObservers(printerObs), initialPressure);
template <template <typename...> class T, typename... Args, typename... Obs>
T<Obs...> MakeSubject(std::tuple<Obs &...> &&obs, Args &&... args)
{
return T<Obs...>(std::move(obs), args...);
}
#include <boost/any.hpp>
int main()
{
std::vector<boost::any> pressures;
Printer printerObs1;
Printer printerObs2;
const int initialPressure = 1;
auto pressure = MakeSubject<Pressure>(
BindObservers(printerObs1, printerObs2), initialPressure);
pressures.push_back(pressure);
pressure.Change(12);
Pressure<Printer> *p = boost::any_cast<Pressure<Printer>>(&pressures[0]);
p->Change(1999); //Bombs
}
//静态\u观察者头文件
#包括
#包括
#包括
枚举类事件类型{未知};
//注意:所有观察者必须对他们希望观察的任何对象类型实施OnNotify
//使用的任何未实现的主题类型都将导致编译器错误
模板类观察者
{
公众:
Observer():obsID_389;(obsIDTracker_389;++){}
模板void OnNotifyImpl(T&subject,EventType event)
{
静态播放(本)->OnNotify(主题、事件);
}
int GetID()常量
{
返回obsID;
}
私人:
int obsID_;
静态int obsIDTracker;
};
模板int-Observer::obsIDTracker_u0;
//递归帮助器结构,用于实现对主题内所有观察者的调用
模板结构NotifyHelper
{
静态void NotifyImpl(T&subject,EventType事件,
std::tuple和obs)
{
std::get(obs).OnNotifyImpl(主题、事件);
NotifyHelper::NotifyImpl(主题、事件、obs);
}
};
模板结构NotifyHelper
{
静态void NotifyImpl(T&subject,EventType事件,
std::tuple&obs){}
};
//有关实例用法,请参见MakeSubject函数
模板类主题
{
公众:
静态常数int numberofobservators=sizeof…(Obs);
主题(std::tuple&&obs):观察者(obs){}
void NotifyAll(EventType事件)
{
NotifyHelper::NotifyImpl(
*静态(本次)、事件、观察员);
}
私人:
std::元组观察者;
};
//用于实现静态主题的CRTP抽象基类。
//子类用法示例--压力传感器:
模板
班级压力:公共科目
{
公众:
typedef主题基类型;
压力(标准::元组和观察者,整数压力)
:BaseType(std::move(observators)),pressure(pressure){}
无效更改(int值)
{
压力=数值;
此->NotifyAll(EventType::UNKNOWN);
}
int GetPressure()常量
{
回油压力;
}
私人:
内压;
};
//用于实现静态主题的CRTP抽象基类。
//子类用法示例--打印观察者:
类打印机:公共观察者
{
公众:
打印机():times(0){}
模板
无效通知(压力和主题,事件类型事件)
{
有趣的是,一旦我问了这个问题,答案就显而易见了。这很有效:
decltype(pressure) *p = boost::any_cast<decltype(pressure)>(&pressures[0]);
p->Change(1999);
decltype(压力)*p=boost::任何铸造(&pressures[0]);
p->Change(1999年);