gpt4 book ai didi

c++ - 尝试学习 BOOST::ANY Q1

转载 作者:行者123 更新时间:2023-11-30 05:47:13 29 4
gpt4 key购买 nike

这个程序在调用时出现段错误

p->Change(1999);

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

我相信下面auto的返回类型

//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);

关于c++ - 尝试学习 BOOST::ANY Q1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28663182/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com