Convenient C++ struct initialisation

后端 未结 13 727
谎友^
谎友^ 2020-12-07 10:15

I\'m trying to find a convenient way to initialise \'pod\' C++ structs. Now, consider the following struct:

struct FooBar {
  int foo;
  float bar;
};
// jus         


        
相关标签:
13条回答
  • 2020-12-07 10:39

    Option D:

    FooBar FooBarMake(int foo, float bar)

    Legal C, legal C++. Easily optimizable for PODs. Of course there are no named arguments, but this is like all C++. If you want named arguments, Objective C should be better choice.

    Option E:

    FooBar fb;
    memset(&fb, 0, sizeof(FooBar));
    fb.foo = 4;
    fb.bar = 15.5f;
    

    Legal C, legal C++. Named arguments.

    0 讨论(0)
  • 2020-12-07 10:40

    Yet another way in C++ is

    struct Point
    {
    private:
    
     int x;
     int y;
    
    public:
        Point& setX(int xIn) { x = Xin; return *this;}
        Point& setY(int yIn) { y = Yin; return *this;}
    
    }
    
    Point pt;
    pt.setX(20).setY(20);
    
    0 讨论(0)
  • 2020-12-07 10:42

    For me the laziest way to allow inline inizialization is use this macro.

    #define METHOD_MEMBER(TYPE, NAME, CLASS) \
    CLASS &set_ ## NAME(const TYPE &_val) { NAME = _val; return *this; } \
    TYPE NAME;
    
    struct foo {
        METHOD_MEMBER(string, attr1, foo)
        METHOD_MEMBER(int, attr2, foo)
        METHOD_MEMBER(double, attr3, foo)
    };
    
    // inline usage
    foo test = foo().set_attr1("hi").set_attr2(22).set_attr3(3.14);
    

    That macro create attribute and self reference method.

    0 讨论(0)
  • 2020-12-07 10:43

    For versions of C++ prior to C++20 (which introduces the named initialization, making your option A valid in C++), consider the following:

    int main()
    {
        struct TFoo { int val; };
        struct TBar { float val; };
    
        struct FooBar {
            TFoo foo;
            TBar bar;
        };
    
        FooBar mystruct = { TFoo{12}, TBar{3.4} };
    
        std::cout << "foo = " << mystruct.foo.val << " bar = " << mystruct.bar.val << std::endl;
    
    }
    

    Note that if you try to initialize the struct with FooBar mystruct = { TFoo{12}, TFoo{3.4} }; you will get a compilation error.

    The downside is that you have to create one additional struct for each variable inside your main struct, and also you have to use the inner value with mystruct.foo.val. But on the other hand, it`s clean, simple, pure and standard.

    0 讨论(0)
  • 2020-12-07 10:51

    Many compilers' C++ frontends (including GCC and clang) understand C initializer syntax. If you can, simply use that method.

    0 讨论(0)
  • 2020-12-07 10:52

    Designated initializes will be supported in c++2a, but you don't have to wait, because they are officialy supported by GCC, Clang and MSVC.

    #include <iostream>
    #include <filesystem>
    
    struct hello_world {
        const char* hello;
        const char* world;
    };
    
    int main () 
    {
        hello_world hw = {
            .hello = "hello, ",
            .world = "world!"
        };
    
        std::cout << hw.hello << hw.world << std::endl;
        return 0;
    }
    

    GCC Demo MSVC Demo

    0 讨论(0)
提交回复
热议问题