如果你真的想擺脫樣板,並且你願意使用預處理器來做到這一點,那麼繼續寫下模式。你擁有的一般模式看起來像
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