尝试学习BOOST::任何Q1



此程序在调用时出错

p->Change(1999);

当我在调试器中运行它时,似乎我进入了Change函数,但在检查时,这个指针是0x00。很明显,我使用BOOST::有错误,但我不确定我做错了什么?

我相信以下的汽车的退货类型

//pressure type = Pressure<Printer, Printer> 
auto pressure = MakeSubject<Pressure>(
                            BindObservers(printerObs1, printerObs2), initialPressure);

当我说时,我可能需要使用decltype和auto与Boost::any

 boost::any_cast<Pressure<Printer>> // change Pressure<Printer> to use decltype<pressure>  ?

但这扩展了我对正在发生的事情的理解。

// 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
}

有趣的是,我一问这个问题,答案就显而易见了。这项工作:

decltype(pressure) *p = boost::any_cast<decltype(pressure)>(&pressures[0]);
p->Change(1999);

相关内容

  • 没有找到相关文章

最新更新