如果您真的想摆脱样板并且您愿意使用预处理器来完成它,那么请继续编写模式。你的一般模式看起来像
extern "C" {
void C_accessible_declaration(); // this is all C sees
}
void Cxx_accessible_declaration_1( int );
void Cxx_accessible_declaration_1( long );
所以你可以做一个宏,
#ifdef __cplusplus
# define C_PORTABLE_FUNCTION_SET( C_DECLS, CXX_DECLS ) \
extern "C" { C_DECLS } \
CXX_DECLS
#else
# define C_PORTABLE_FUNCTION_SET( C_DECLS, CXX_DECLS ) \
C_DECLS
#endif
这是有效的,因为普通函数声明不能包含未用括号括起来的逗号。如果您希望它与模板一起使用(使用逗号分隔的模板参数),那么您可以在 C99、C++11 和这些标准之前的各种编译器中支持的可变参数宏作为扩展。
#ifdef __cplusplus
# define C_PORTABLE_FUNCTION_SET( C_DECLS, ... ) \
extern "C" { C_DECLS } \
__VA_ARGS__
#else
# define C_PORTABLE_FUNCTION_SET( C_DECLS, ... ) \
C_DECLS
#endif
现在只要 C 声明不包含裸逗号,这就会起作用,这意味着您不应该在一个声明中声明多个对象。我调用它是C_PORTABLE_FUNCTION_SET
为了强调它主要用于函数声明是安全的,但请注意,您还需要在其中声明 C 可访问对象extern C
。共享struct
定义根本不应该受到保护;它们受到 C++ POD 概念的保护,并且不带有语言链接。
用法:
#ifdef __cplusplus
template< typename T, typename U >
class Buffer { // still use #ifdef for the general case
...
};
#endif
C_PORTABLE_FUNCTION_SET (
void ArrayList_insert(ArrayList *arrlst, void *data, int i);
, /* C++ */
void ArrayList_insert(ArrayList *arrlst, char *data, int i);
template< typename T, typename U >
void ArrayList_insert(ArrayList *arrlst, Buffer< T, U > &data, int i);
)
我不认为我自己会这样做,但它似乎足够安全,可以成为惯用语。