如果你真的想摆脱样板,并且你愿意使用预处理器来做到这一点,那么继续写下模式。你拥有的一般模式看起来像
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
以强调它主要用于函数声明是安全的,但请注意,您还需要在extern C
之内声明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);
)
我不认为我会这样做我自己,但似乎足够安全成为习惯。
这会在用c编译时导致错误,因为c不支持函数重载。 – chacham15
chacham15 - 你是对的。我确定了答案,因为我误解了这个问题。 –
现在它相当于@Carl Norum的答案。 – chacham15