您可以定义一个带有 void * 初始化参数和枚举的“构造函数”:
enum StringCtor { SC_DEFAULT, SC_C_STR, SC_COPY };
String new_String(enum StringCtor type, const void *arg);
String s1 = new_String(SC_DEFAULT, 0);
String s2 = new_String(SC_C_STR, "hello");
String s3 = new_String(SC_COPY, &s2);
您也可以选择使用 a...
而不是 a void *
。想法是一样的,但是va_*
如果参数应该是字符串或副本,您可以使用宏来提取参数。
如果您只希望 API 具有单个构造函数的外观,但仍希望类型安全,则可以使用上述技术来创建实际的构造函数实现,并使用内联函数和预处理器技巧来赋予单个构造函数的外观,具有类型安全性。
String new_StringImpl(enum StringCtor type, const void *arg);
static inline String new_StringImplDefault () {
return new_StringImpl(SC_DEFAULT, 0);
}
static inline String new_StringImplCstr (const char *s) {
return new_StringImpl(SC_C_STR, s);
}
static inline String new_StringImplCopy (String *s) {
return new_StringImpl(SC_COPY, s);
}
#define new_String_Paste(TYPE) new_String_ ## TYPE
#define new_String_SC_DEFAULT(ARG) new_StringImplDefault()
#define new_String_SC_C_STR(ARG) new_StringImplCstr(ARG)
#define new_String_SC_COPY(ARG) new_StringImplCopy(ARG)
#define new_String(TYPE, ...) new_String_Paste(TYPE)(__VA_ARGS__)
String s1 = new_String(SC_DEFAULT);
String s2 = new_String(SC_C_STR, "hello");
String s3 = new_String(SC_COPY, &s2);
注意使用可变参数宏,SC_DEFAULT
不再需要第二个参数。在足够的优化级别上,代码仅转换为对单个实现函数的调用,并具有编译时类型安全检查的好处。因此,以您编写更多代码为代价,您可以为库的用户提供单个构造函数 API 的外观,并具有多个构造函数的所有类型安全性。