我试图创建一个宏来根据参数的数量选择对象实例化。宏必须支持零到两个参数。 所需的结果是选择以下三个中的一个,并传递0到2个参数(如果有):
MyClass obj(hardcoded_arg); // Choose this one if no arguments passed to a macro
MyClass obj(hardcoded_arg,arg1); // This one if a single argument passed
MyClass obj(arg1,arg2); // This one if two arguments passed
以下是我试图实现这一目标的方法:
#define TYPE1(...) MyClass obj(hardcoded_arg);
#define TYPE2(arg1) MyClass obj(hardcoded_arg,arg1);
#define TYPE3(arg1,arg2) MyClass obj(arg1,arg2);
#define EXPAND( x ) x
#define GET_TYPE(DUMMY, _1 ,_2, NAME, ...) NAME
#define INSTANTIATE(...) EXPAND(GET_TYPE(DUMMY ,##__VA_ARGS__, TYPE3, TYPE2, TYPE1))(__VA_ARGS__)
INSTANTIATE()
INSTANTIATE(1)
INSTANTIATE(1,2)
我尝试使用像
这样的定义 #define VA_ARGS(...) , ##__VA_ARGS__
#define INSTANTIATE(...) EXPAND(GET_TYPE(DUMMY VA_ARGS(__VA_ARGS__), TYPE3, TYPE2, TYPE1))(__VA_ARGS__)
但它也没有解决这个问题。 像INSTANTIATE(,)这样的解决方案很蹩脚。
感谢任何建议!
答案 0 :(得分:1)
工厂功能过载怎么样?像
MyClass create() { return MyClass(hardecoded_arg); }
MyClass create(type2 arg2) { return MyClass(hardcoded_arg, arg2); }
MyClass create(type1 arg1, type2 arg2) { return MyClass(arg1, arg2); }
类型安全,无需使用预处理器进行操作。
答案 1 :(得分:0)
如果MyClass
的构造函数不是explicit
,也不与initializer_list构造函数冲突,则可以使用以下不调用移动/复制构造函数的构造函数:
MyClass make_MyClass() { return {hardcoded_arg}; }
template <typename T>
MyClass make_MyClass(T&& arg) { return {hardcoded_arg, std::forward<T>(arg)}; }
template <typename T1, typename T2>
MyClass make_MyClass(T1&& arg1, T2&& arg2)
{
return {std::forward<T1>(arg1), std::forward<T2>(arg2)};
}