C++ 中的任何方式转发声明函数原型?

发布于 2024-08-27 06:19:03 字数 762 浏览 9 评论 0原文

我经常使用前向类声明和指向此类的指针。

我现在需要通过多个层传递函数指针。我更愿意将声明函数指针原型的标头仅包含到取消引用函数指针的模块中,而不是包含到仅传递该指针值的每个层中。

这可能吗?

=====

从回复来看我怀疑我的问题表达得不够清楚。我寻求类似于前向类声明的方法。我们都同意我可以写:

class foo;

无效栏(foo*);

无效 waz(foo* p) { 酒吧(p);请

注意,waz 除了类 foo 的名称之外,对它一无所知。也许 bar 将能够访问 foo 的完整描述。也许 bar 只会让 p 继续前进。谁在乎?仅那些取消引用 foo* 的网站。所有其他站点只需要“class foo;”。

同样,我知道我可以写:

typedef void foo(int, double);

无效栏(foo*);

无效 waz(foo* p) { 酒吧(p); 不同之处在于

,现在标识符 foo 不仅已知表示函数类型,而且还已经携带了完整的签名/原型。这迫使我陷入两种不愉快的情况之一:

1)在多个站点克隆 typedef(恶心!脆弱!) 2) 将 typedef 粘贴在标头中,并在提到 foo* 的任何地方都包含它。

请注意不对称性:对于数据对象,我只需要在想要取消引用 foo* 的那些点处提供类 foo 的完整描述;对于函数,我需要在我想提到 foo* 的任何地方提供完整的签名/原型。

那么有什么办法可以弥补这种不对称性吗?

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. 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

画中仙 2024-09-03 06:19:03

您可以使用未定义的结构类型来执行此操作,但需要额外取消引用。

将其放入主头文件中:

typedef struct FuncStruct *FuncPtr;

这声明了 struct FuncStruct 但未声明任何字段,然后它声明了一个指向该结构的指针,称为 FuncPtr。您可以传递 FuncPtr,但不能取消引用它们。

那么在一个特定的文件(或更具体的 .h 文件)中,您实际上可以像这样定义一个 struct FuncStruct

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

然后通过此定义的代码可以取消引用 FuncPtr 来获取实际的函数指针。

请注意,这是对强制转换的额外取消引用,这意味着您需要对 FuncStruct 进行一些内存管理。

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.

顾冷 2024-09-03 06:19:03

对于传递函数指针,您只需要知道参数类型和返回类型:

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

这里,f() 是一个函数,它接受一个函数指针,指向一个采用 int 的函数> 并返回void

typedef 使其更具可读性:

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

通常,您可能想查看函子或使用例如 Boost.FunctionBoost.Bind。这样您还可以传入绑定成员函数或函数对象:

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

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

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

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));
·深蓝 2024-09-03 06:19:03

当然,例如

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

现在你可以传递它

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

Sure, e.g.

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

Now you can pass it around

void foo(FOOFUNC f) {
  f(...);
}
撩起发的微风 2024-09-03 06:19:03

我完全理解OP想要做什么。事实上,我也想做同样的事情。根据OP所说的,我有以下内容(用C,而不是C++):

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

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

问题是,Bh是否必须包含Ah? Ah 定义了我不想包含在 Bh' 中的各种其他内容,因此我希望这是一种“前向引用”函数指针的方法,而无需在 Bh' 中的 typedef 中重新定义它/code>Bh`(这可能根本不起作用)?

或者编译器是否需要更多地了解 Bh 中的 f_t,而不是前向引用的 struct

我也可能需要重新考虑代码的布局,但我同意OP的观点,即在完美的世界中,函数指针和其他可以前向引用的对象之间应该存在某种对称性。

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.

小红帽 2024-09-03 06:19:03

完全有可能。您可以在任何需要的地方复制函数原型,但当我看到这样做很多时,警钟就开始响起。

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.

沐歌 2024-09-03 06:19:03

从你的问题中并不清楚你想做什么。

首先,C++ 中不存在“原型”这样的东西。 “原型”(函数原型)的概念仅是 C 语言特有的。

其次,您在消息正文中提到了一些“函数指针的原型”,而标题则谈到了“函数原型”。这使得事情变得更加混乱。 “函数指针的原型”没有任何意义。即使在 C 中,也不存在指针的“原型”这样的东西,更不用说 C++ 了。

那么,你想做什么?如果你想前向声明一个函数 - 只需声明它即可。

如果您想前向声明一个指针 - 也只需声明它即可。为了获得对象的声明(非定义声明),只需使用 extern 关键字进行声明即可。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文