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

a macro to choose the object instantiation based on the amount of the arguments

本文关键字:参数 选择 实例化 对象 一个 用于      更新时间:2023-10-16

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

任何建议都是感激的!

如何重载工厂函数?像

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

类型安全,不需要在预处理器上耍花招

如果MyClass的构造函数不是explicit,也不与initializer_list的构造函数冲突,则可以使用以下不调用move/copy构造函数的方法:

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)};
}
演示