扩展 C 宏时的“预期主表达式”

gla*_*des 0 c++ struct aggregate c-preprocessor preprocessor-directive

我正在尝试默认初始化一个配置结构,该结构由一些字段组成,其中包括另一个从属配置结构 - 使用宏:

现场演示

#include <cstdio>

#define MYCLASS_DEFAULT_CONFIG mylib::options { \
    .a_ = 2, \
    .b_ = 3, \
    .subopts_ = MYCLASS_DEFAULT_SUBOPT_CONFIG() \
}

#define MYCLASS_DEFAULT_SUBOPT_CONFIG mylib::sub_options { \
    .c_ = 'A'; \
    .d_ = 'H'; \
}


namespace mylib
{
    struct sub_options
    {
        char c_;
        char d_;
    };

    struct options
    {
        int a_;
        int b_;
        sub_options subopts_;
    };


    class myclass
    {
        myclass(options opts)
            : opts_ { opts }
        {
            
        }

        options opts_;
    };
}

int main()
{
    mylib::myclass some_class(MYCLASS_DEFAULT_CONFIG());
    
    return 0;

}
Run Code Online (Sandbox Code Playgroud)

我不太确定为什么这不起作用,因为 x86 gcc 12.2 给了我:

<source>:3:47: error: expected primary-expression before '{' token
    3 | #define MYCLASS_DEFAULT_CONFIG mylib::options { \
      |        
Run Code Online (Sandbox Code Playgroud)

我缺少什么主要情绪?

Kam*_*Cuk 6

.c_ = 'A'; \
Run Code Online (Sandbox Code Playgroud)

列表元素初始化用逗号分隔,而不是;。是{ .c_ = 'a', },不;,但是有,

#define MYCLASS_DEFAULT_CONFIG mylib::options { ... }

MYCLASS_DEFAULT_CONFIG()
Run Code Online (Sandbox Code Playgroud)

它们()字面意思理解并保持原样。你的代码最后变成了mylib::options { ... }()假的。()要么创建一个宏函数#define MYCLASS_DEFAULT_CONFIG(),要么删除().

class myclass
{
    myclass()...
}

mylib::myclass 
Run Code Online (Sandbox Code Playgroud)

myclass构造函数是私有的。你不能从 main 调用它。


不管怎样,为什么要用宏呢?只需使用变量即可。考虑:

namespace mylib {
    struct sub_options {
        char c_;
        char d_;
    };
    struct options {
        int a_;
        int b_;
        sub_options subopts_;
    };
    class myclass {
        options opts_;
    public:
        myclass(options opts) : opts_{opts} {}
    };
    static constexpr mylib::sub_options sub_options_default{
        .c_ = 'A',
        .d_ = 'H',
    };
    static constexpr mylib::options myclass_default_config{ \
        .a_ = 2,
        .b_ = 3,
        .subopts_ = sub_options_default,
    };
}
int main() {
    mylib::myclass some_class(mylib::myclass_default_config);
}
Run Code Online (Sandbox Code Playgroud)