在c中使用重载的c++函数

Posted

技术标签:

【中文标题】在c中使用重载的c++函数【英文标题】:Using overloaded c++ function in c 【发布时间】:2019-07-22 21:48:33 【问题描述】:

我之前用 C++ 代码编写了一个重载函数,现在我需要从 C 文件中调用该函数。不幸的是,在我在 C 中包含 c++ 头文件后,Makefile 无法编译。 (我正在使用带有 c++11 标志的 g++)

这是我的问题:

    程序不编译是因为 C 不支持函数重载吗?

    如果 (1) 是这种情况,我可以采取哪些其他选项来使用重载函数?

cplusplus.h

#ifndef CPLUSPLUS_H
#define CPLUSPLUS_H

#ifdef __cplusplus
 extern "C" 
"#endif"

void Foo(A a);
void Foo(B b);

#ifdef __cplusplus
 
"#endif"


cplusplus.cxx

#include "cplusplus.h"

extern "C" 

   void Foo(A a) 
      print(a.some_member);
   

   void Foo(B b) 
      print(b.some_member);
   



main.c

#include "cplusplus.h"

int main(int argc, char*argv[]) 
   return 0; //Even without calling the function, an error throws.

【问题讨论】:

C 不支持函数重载。 是的,C 不支持重载。因此,当您在 C 源文件中包含“cplusplus.h”时,您包含的代码不是合法的 C 代码且无法编译。 为了你的理智,假设 C 是 python 而 C++ 是 JS。你不能混合 python 和 JS 就像你不能(你可以但假装)混合 C 和 C++。 可能的骗子:***.com/questions/2351792/does-c-support-overloading 我将避免投票结束,因为如果我投票,将立即关闭。 如果你真的想要重载之类的东西,你可以尝试使用 C11 的_Generic,但它仍然需要对你的 C++ 代码进行一些修改才能使其工作。 【参考方案1】:
    程序不编译是因为 C 不支持函数重载吗?

正确。

    如果是 (1),我可以采取哪些其他选项来使用重载函数?

如果你只需要调用其中一个函数,那么你可以为它写一个单独的头,这样你就可以在没有另一个重载的情况下声明它。

如果您需要同时调用两者,那么您可以编写具有不同名称的包装函数,以提供与 C 兼容的 API。

【讨论】:

【参考方案2】:

程序不编译是因为C不支持函数重载吗?

是的。

如果是 (1),我可以采取哪些其他选择?

C 接口必须使用未重载的函数名称,并且不使用任何其他不兼容的 C++ 工件。例如,您不能在 extern "C" 函数中使用引用类型。


// C++ functions
void Foo(A a) 
   print(a.some_member);


void Foo(B b) 
   print(b.some_member);


// C-compatible layer.
extern "C" 

   void Foo_A(A a) 
      Foo(a);
   

   void Foo_B(B b) 
      Foo(b);
   

【讨论】:

【参考方案3】:

C 不支持 C++ 的重载,但 C11 标准确实带来了自己的风格,您可以借助一些包装函数来使用它。

首先让我们从一个基本的 cpp 源文件开始,该文件带有一个重载函数,用于打印传递给它的值:

foo.cpp

#include "foo.h"

#include <cstdio>

void Foo(int a) 
    printf("%d\n", a);


void Foo(float b) 
    printf("%f\n", b);


#ifdef __cplusplus
extern "C" 
#endif // __cplusplus

// wrapper functions for use in C
void FooA(int a) 
    Foo(a);


void FooB(float b) 
    Foo(b);


#ifdef __cplusplus

#endif // __cplusplus

现在有了头文件,我们执行了一些通用的宏魔术来使 C 中的重载工作。

foo.h

#ifndef FOO_H
#define FOO_H

// C can't handle these overloaded functions, so only let C++ see them
#ifdef __cplusplus
void Foo(int a);
void Foo(float b);

// C++ won't be needing these wrappers
#else
void FooA(int a);
void FooB(float b);

// Where the magic happens
#define Foo(X) _Generic((X), \
    int: FooA((X)), \
    float: FooB((X)) \
)
#endif // __cplusplus
#endif // FOO_H

还有一个简单的 C 文件来证明它有效

ma​​in.c

#include "foo.h"

int main(void) 
    int x = 4;
    float y = 3.2f;

    Foo(x);
    Foo(y);

编译我们的源代码,它干净利落,没有任何警告

gcc -Wall -Wextra -Wpedantic -std=c11 -c main.c -o main.o
g++ -Wall -Wextra -Wpedantic -std=c++11 -c foo.cpp -o foo.o
gcc  -o bin main.o foo.o

运行它,我们得到:

$ ./bin
4
3.200000

就是这样,只需在头文件中做一些工作,就可以像使用 C++ 源代码一样在 C 源代码中使用重载函数。

【讨论】:

以上是关于在c中使用重载的c++函数的主要内容,如果未能解决你的问题,请参考以下文章

什么是C++重载?

使用 extern "C" 时 C++ 代码中的函数重载

C/C++编程笔记:C++中的函数重载

C++函数的重载

C++函数的重载

C++之函数重载