开发者

Any way in C++ to forward declare a function prototype?

开发者 https://www.devze.com 2022-12-25 19:57 出处:网络
I make regular use of forward class declarations and pointers to such classes. I now have a need to pass a function pointer through a number of layers. I would prefer to include the header that decla

I make regular use of forward class declarations and pointers to such classes.

I now have a need to pass a function pointer through a number of layers. I would prefer to include the header that declares my function pointer's prototype only into the module that dereferences a function pointer rather than into each layer that simply passes along that pointer value.

Is this possible?

=====

From the replies I suspect that I have not expressed by question clearly enough. I seek an analog to a forward class declaration. We all agree that I can write:

class foo;

void bar(foo*);

void waz(foo* p) { bar(p); }

Notice that waz knows nothing about class foo other than its name. Perhaps bar will have access to foo's complete description开发者_如何学Python. Perhaps bar will simply pass p further along. Who cares? Only those sites that dereference a foo*. All other sites need only "class foo;".

Similarly I know that I can write:

typedef void foo(int, double);

void bar(foo*);

void waz(foo* p) { bar(p); }

The difference is that now the identifier foo not only is known to denote a function type but further already carries the full signature/prototype. This forces me into one of two unpleasant scenarios:

1) clone the typedef at multiple sites (yuck! fragile!) 2) stick the typedef in a header and include it everywhere that a foo* is mentioned.

Notice the asymetry: in the case of a data object I only needed to provide a complete description of class foo at those points where I want to dereference a foo*; in the case of a function I need to provide the full signature/prototype everywhere I want to mention a foo*.

So is there anyway to remedy this asymmetry?


You can do this using an undefined structure type, at the cost of an extra dereference.

put this in the main header file:

typedef struct FuncStruct *FuncPtr;

This declares struct FuncStruct but does not declare any fields, then it declares a pointer to this struct called FuncPtr. You can pass FuncPtrs around but you can not dereference them.

then in a particular file (or a more specific .h file), you can actually define a struct FuncStruct like this:

struct FuncStruct {
  int (*f)(int, char, double);
};

Then code past this definition can dereference a FuncPtr to get the actual function pointer.

Note this is an extra dereference from just a cast, and it means you'll need to do some memory management of FuncStructs.


For passing function pointers you only need to know the argument types and the return type:

void f(void (*func)(int));

Here, f() is a function that takes a function pointer to a function that takes an int and returns void.

typedefs make that more readable:

typedef void (*FuncPtr)(int);
void f(FuncPtr func);

In general you might want to look at functors or using e.g. Boost.Function and Boost.Bind. That way you can also pass in bound member functions or function objects:

void f(boost::function<void (int)> fn) {
    fn(42);
}

struct X {
    void f(int) {}
};

// ...
X x;
f(boost::bind(&X::f, &x, _1));


Sure, e.g.

typedef void (*FOOFUNC)(int x, int y, char z);

Now you can pass it around

void foo(FOOFUNC f) {
  f(...);
}


I understand exactly what the OP is trying to do. In fact, I want to do the same thing. Following on what the OP said, I have the following (in C, not C++) :

/* File A.h */
typedef void (*f_t)(int x);

/* File B.h */
typedef void (*call_f_t)(f_t func2call,int y);

The question is, does B.h have to include A.h? A.hdefines all sorts of other things I would rather not include in B.h', so I am hoping is a way to "forward reference" a function pointer, without redefining it in a typedef inB.h` (which probably doesn't even work)?

Or does the compiler need to know more about f_t in B.h than it would about, say, a forward referenced struct?

It is also possible that I need to rethink the layout of my code, but I agree with the OP, that in a perfect world, there should be some sort of symmetry between function pointers and other objects that can be forward-referenced.


Totally possible. You can copy your function prototype wherever you need it, though when I see this done a lot, alarm bells start to go off.


It is not clear from your question what you are tryng to do.

Firstly, there's no such thing as "prototype" in C++. The concept of "prototype" (function prototype) is specific to C language only.

Secondly, you mention some "function pointer's prototype" in the message body, while the caption talks about "function prototype". This makes it even more confusing. "Function pointer's prototype" makes no sense. There's no such thing as "prototype" for a pointer, even in C, let alone C++.

So, what is it you want to do? If you want to forward-declare a function - just declare it.

If you want to forward-declare a pointer - also just declare it. In order to obtain a declaration (a non-defining declaration) of an object, just declare it with an extern keyword.

0

精彩评论

暂无评论...
验证码 换一张
取 消