- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试编译一个实例化此类的文件。 GCC 给了我神秘的错误,但 clang 毫无怨言地编译了它。
错误:
statemachine.h: In member function ‘void state_machine<Data, T>::start_submachine(void (*)(state_machine<Data, T>&, T), void (*)(state_machine<Data, T>&, T))’:
statemachine.h:245: error: ‘substate_machine<Data, T>::substate_machine(state_machine<Data, T>*)’ is protected
statemachine.h:215: error: within this context
statemachine.h: In member function ‘state_machine<Data, T>* substate_machine<Data, T>::parent()’:
main.cpp:282: instantiated from here
statemachine.h:138: error: ‘state_machine<Data, T>* state_machine<Data, T>::parent()’ is protected
statemachine.h:241: error: within this context
statemachine.h: In member function ‘void substate_machine<Data, T>::state_return()’:
main.cpp:282: instantiated from here
statemachine.h:232: error: ‘void state_machine<Data, T>::return_from_sub()’ is protected
statemachine.h:254: error: within this context
Main.cpp 有 282 行长,它指向的行只是一个右括号}。 Parent() 永远不会在类外被调用(那么为什么它会提示它被保护了)?为什么它会提示 state_return() 调用 protected 方法,因为这是类的成员。 GCC/G++ 是否搞砸了模板中 protected 数据成员?我怀疑(这只是一种预感)它正在尝试内联扩展像宏这样的函数……但为什么呢?
代码:
#ifndef STATEMACHINE_H_INC
#define STATEMACHINE_H_INC
//#include <iostream> TODO: Make better templated stream type
#include <memory>
#include <string>
const std::string null_string = "";
/* Class state_machine:
* Templated class to allow easy implementation of FSMs.
*
* HOW TO USE:
* - Make a type containing whatever data needs to be passed
* to the current state.
* - If necessary, create a preprocessor function run before
* the actual state is invoked (prefunc)
* - Create a function for each state. In addition, each
* state can be made a submachine by using substate_machine
* - If necessary, specialize (INLINE and in the HEADER FILE)
* the finalize() method.
* - The function names should pretty much be self explanitory.
*
* Hooray for function pointers. The code was 5x longer and 10x
* buggier before I implemented lexer as a state machine :D.
*
* NOTE: This class COPY CONSTRUCTS from the hints provided (at least
* for now), so *don't* try and use your old pointer- it's not the
* same object! This was done to simplify this class's
* implementation. At some point I should probably change it...
*
*/
template <class Data, class T>
class state_machine {
public:
//public use typedefs
typedef void (*state)(state_machine<Data, T>&, T);
typedef state prefunc_t;
static void defprefunc(state_machine<Data, T>&, T);
static void defstate(state_machine<Data, T>&, T);
static void submachine_handle(state_machine<Data, T>&, T);
//The above works with submachines because references are treated
//by the standard like pointers- so polymorphism is allowed
private:
prefunc_t prefunc;
//don't feel like writing a full on destructor for one pointer
std::auto_ptr<Data> internal_data;
state curstate;
state returnstate;
//this MUST be an auto_ptr or our memory management gets REAL tricky
std::auto_ptr < state_machine<Data, T> > substate;
protected:
void init();
void call(state_machine<Data, T>&, T);
//this method allows submachine to get data from top of hierarchy.
virtual state_machine<Data, T> * parent(); //return TOP of tree
void return_from_sub(); //this is a slot, to use the qt term
public:
//public interface
state_machine(prefunc_t = defprefunc, Data * = NULL);
Data& data();
void change_state(state);
//TODO: change std::istream to a stream dependent on T
//void add_stream(std::istream&);
void add_char(T);
//NULL here means curstate:
void start_submachine(state, state = NULL);
//this method is available for specialization
void finalize();
virtual void state_return();
};
/* class substate_machine:
* This class is a helper class to allow the creation of state
* machines as states within another state machine. Submachines:
* -Share the same data.
* -Behave exactly like a regular state, except upon exiting
* the submachine the state should call the state_return()
* method, which allows control to flow to the parent machine.
* -Are invoked with the start_submachine() method.
* Basically, what allows them to share data is the protected
* virtual method parent(), which gets the state_machine object
* at the hierarchy's root. This is never used by the submachine,
* only in the parent machine methods when accessing shared data
* (i.e. the subclass provides 'plug-in' functionality with this
* method), so it *could* be made a private virtual, but those seem
* to be 1. poorly understood and 2. overprotective in cases like
* this (i.e. do we *really* care if the submachine knows how to
* access its parent? no, in fact, we encourage it).
*
* The user should never see this class. It is only to be used
* by the state_machine parent class provide transparent operation
* of substates (don't you love polymorphism>)
*/
template <class Data, class T>
class substate_machine : public state_machine<Data, T> {
state_machine<Data, T> * parentsm; //direct parent state machine
substate_machine() {} //Default construction causes failure
protected:
virtual state_machine<Data, T> * parent();
substate_machine(state_machine<Data, T>*);
public:
virtual void state_return(); //send a signal to the parent machine
};
// definitions
//note that state_machine<Data, T>::parent() returns the TOP of the
//hierarchy, NOT the direct parent.
template <class Data, class T>
state_machine<Data, T> * state_machine<Data, T>::parent() {
return this; //base class state machine must be at top of hierarchy
}
template <class Data, class T>
void state_machine<Data, T>::finalize() {
//this is left to be <intentionally> specialized over
}
template <class Data, class T>
Data& state_machine<Data, T>::data() {
//use parent here to allow all subs to access the hierarchy's shared
//data as if they own it.
return *(parent()->internal_data);
}
//these are two different functions for clarity's sake
template <class Data, class T>
void state_machine<Data, T>::defstate
(state_machine<Data, T>& self, T c) {
//do nothing - default behavior
}
template <class Data, class T>
void state_machine<Data, T>::defprefunc
(state_machine<Data, T>& self, T c) {
//do nothing - default behavior
}
template <class Data, class T>
void state_machine<Data, T>::
submachine_handle(state_machine<Data, T>& self, T c) {
//handle a submachine
self.substate->curstate(*(self.substate), c);
}
template <class Data, class T>
void state_machine<Data, T>::state_return() {
//should NOT happen, but handle just in case.
}
template <class Data, class T>
void state_machine<Data, T>::init() {
curstate = defstate;
prefunc = defprefunc;
}
template <class Data, class T>
state_machine<Data, T>::state_machine
(prefunc_t func, Data * d) {
init();
//make a new data - copy construct if d is not null
if (d) {
internal_data = std::auto_ptr<Data>(new Data(*d));
}
else {
internal_data = std::auto_ptr<Data>(new Data);
}
prefunc = func;
}
template <class Data, class T>
void state_machine<Data, T>::change_state(state s) {
curstate = s;
}
//the first state is the state to start a submachine in, the second
//state is the state to go into when the submachine returns to the
//parent, which is by default NULL (the current state)
template <class Data, class T>
void state_machine<Data, T>::start_submachine(state s, state rs) {
//get arround default argument errors (static resolution...)
if (rs == NULL) {
rs = curstate;
}
//set up submachines
substate = std::auto_ptr<state_machine<Data, T> >(new substate_machine<Data, T>(this));
substate->change_state(s);
returnstate = rs;
//set up the submachine state handler
curstate = submachine_handle;
}
//preprocess and then process a character through the state machine.
template <class Data, class T>
void state_machine<Data, T>::add_char(T c) {
prefunc(*this, c);
curstate(*this, c);
}
//this is a slot for the submachine to send its return signal to.
//basically just switches the function pointer back.
template <class Data, class T>
void state_machine<Data, T>::return_from_sub() {
curstate = returnstate;
}
//now for the substate
template <class Data, class T>
state_machine<Data, T> * substate_machine<Data, T>::parent() {
//remember, this is the top of the hierarchy.
return parentsm->parent();
}
template <class Data, class T>
substate_machine<Data, T>::
substate_machine(state_machine<Data, T> * sm) {
this->init();
parentsm = sm;
//initialization. MUST BE INITIALIZED BY A PARENT THROUGH THIS CTOR
}
template <class Data, class T>
void substate_machine<Data, T>::state_return() {
parentsm->return_from_sub();
//sends the parent the return signal.
}
#endif
提前感谢您的任何意见。我会用 clang++ 标记,但它不允许我...
最佳答案
正如编译器所说,这些东西都受到了保护。父类不能调用派生类的 protected 构造函数(反之亦然)。
class A
{
protected:
A(int) {}
public:
void foo();
};
class B: public A
{
protected:
B(int):
A(10) //OK here
{}
};
void A::foo()
{
B b(10); //error, that constructor is not accessible to A
}
而 substate_machine 的父方法确实试图通过静态类型不是 substate_machine 的指针调用 protected 方法。
class A
{
protected:
void foo() {}
};
class B: public A
{
void bar() {
this->foo(); //OK
B other_b;
other_b.foo(); //OK
A a;
a.foo(); //not OK
A* b_ptr = &other_b;
b_ptr->foo(); //not OK, static type of *b_ptr is not B
}
};
我想知道您是否希望 protected
表示“只要两个类属于同一继承树,任何类都可以访问任何其他类的 protected 部分”?...
关于c++ - g++ 中的奇怪编译错误(clang++ 编译正常),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5023145/
我目前正在尝试让 g++ 工作,并查看 http://gcc.gnu.org/install/build.html ,我似乎找不到它在哪里说如何“执行编译器的 3 阶段 bootstrap ”。我在哪
James Powell 在他对即将举行的演示文稿的简短描述中说,他自豪地发明了最粗糙的 Python 单行代码之一: (None for g in g if (yield from g) and F
请告诉我我的证明是否正确 We have a connected graph, and specific vertex u in V(G). Suppose we compute the dfs tr
下面的test2和test3结果是不同的。 我对此感到困惑,因为它看起来像相同的逻辑,并且与linux bash ||逻辑不同。 $data = @( [PSCustomObject]@{St
我试图找到一个明确的 G 代码语法规范,而不是单个 G 代码的含义,我无处不在的规范,我的意思是详细的语法规范,目的是编写解析器。 我编写解析器没有问题,我只是在寻找语法规范,例如。我知道您不必总是为
我写了这个 mixin,但它循环了很多时间。你能帮我优化我的代码吗?或者你能建议一些其他的东西来获得想要的结果吗? dfgdfgsdfgsdf 最佳答案 希望这就是您要找的。 $spaces: (4,
默认情况下,g++ 似乎会省略未使用的类内定义方法的代码。示例 from my previous question : struct Foo { void bar() {} void baz(
是否可以将文件内容通过管道传送到 g++编译程序? 我想这样做是因为我想使用数据库中的文件而不是磁盘上的物理文件。可以通过我制作的 API 轻松检索文件内容。 例如,我想做这样的事情: g++ con
如何profile c++代码获取每行代码的调用次数和消耗时间,就像profile工具一样在 Matlab 中呢? 我尝试使用-fprofile-arcs之类的东西,但它只生成代码覆盖率报告,其中可以
如何在几行代码上禁用所有警告。可以使用 GCC 诊断功能禁用特定警告,但是否有针对所有警告的标志。我尝试了这个方法,但不起作用 #pragma GCC diagnostic push #pragma
我有一个链接到 opencv 2.2 的可执行文件。但是,我删除了 opencv 2.2 并安装了 opencv 2.3。 问题是,有没有办法在不重新编译整个源代码的情况下将这个可执行文件链接到新的共
在编译带有一些标志的以下文件时,是否可以让 g++ 显示错误? #include using namespace std; int main() { int arr[ 2 ]; cout
在学习 Haskell 时,我遇到了一个挑战,要找到两个函数 f 和 g,例如 f g 和 f 。 g 是等价的(并且是总计,因此像 f = undefined 或 f = (.) f 这样的东西不算
根据我的理解,Theta 位于 Big O 和 Omega 之间,但我看到了这个声明,但我无法理解为什么交集会出现在这里。我能否对 Θ(g(n)) = O(g(n)) ∩ Ω(g(n)) 获得数学和分
我需要为这个递归函数编写一个迭代函数。 int funcRec(int n){ if(n>1) { return 2*funcRec(n - 1) + 3*funcRec(n
我在 github repository 上有代码示例并在 travis-ci 上创建了一个构建便于复制。 最小的、完整的和可验证的例子 可能不是最小的,但我相信它足够小 它使用 boost.inte
编辑:我们将调用箭头 p纯如果存在这样的函数f即:p = arr f . 我试图更好地掌握 Haskell 中的 Arrows,我想弄清楚什么时候 f >>> (g &&& h) = (f >>> g
我有两个(或更多)函数定义为: val functionM: String => Option[Int] = s => Some(s.length) val functionM2: Int => Op
好像是的。任何直观或严肃的证据都值得赞赏。 最佳答案 没有。 我认为您的问题等同于:给定函数 f 和 g,f 是 O(g) 或 g 是 O(f) 是否总是正确的?这在 SE Computer Scie
如果我设法证明 f(n) = o(g(n))(小 o),那么这两个函数的总和 f( n) + g(n) 应该被“更大”的函数 g(n) 紧紧束缚。 然而,我在证明这一点时遇到了一些麻烦。 最佳答案 以
我是一名优秀的程序员,十分优秀!