一个宏,用于根据参数的数量选择对象实例化

时间:2016-11-01 14:57:33

标签: c++ macros

我试图创建一个宏来根据参数的数量选择对象实例化。宏必须支持零到两个参数。 所需的结果是选择以下三个中的一个,并传递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(,)这样的解决方案很蹩脚。

感谢任何建议!

2 个答案:

答案 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)};
}

Demo