Convenient C++ struct initialisation

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

struct FooBar { int foo; float bar; }; // just to make all examples work in C and C++: typedef struct FooBar FooBar;

If I want to conveniently initialise this in C (!), I could simply write:

/* A */ FooBar fb = { .foo = 12, .bar = 3.4 }; // illegal C++, legal C

Note that I want to explicitly avoid the following notation, because it strikes me as being made to break my neck if I change anything in the struct in the future:

/* B */ FooBar fb = { 12, 3.4 }; // legal C++, legal C, bad style?

To achieve the same (or at least similar) in C++ as in the /* A */ example, I would have to implement an idiotic constructor:

FooBar::FooBar(int foo, float bar) : foo(foo), bar(bar) {} // -> /* C */ FooBar fb(12, 3.4);

Which is good for boiling water, but not suitable for lazy people (laziness is a good thing, right?). Also, it is pretty much as bad as the /* B */ example, as it does not explicitly state which value goes to which member.

So, my question is basically how I can achieve something similar to /* A */ or better in C++? Alternatively, I would be okay with an explanation why I should not want to do this (i.e. why my mental paradigm is bad).

EDIT

By convenient, I mean also maintainable and non-redundant.

-------------Problems Reply------------

Since style A is not allowed in C++ and you don't want style B then how about using style BX:

FooBar fb = { /*.foo=*/ 12, /*.bar=*/ 3.4 }; // :)

At least help at some extent.

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.

Your question is somewhat difficult because even the function:

static FooBar MakeFooBar(int foo, float bar);

may be called as:

FooBar fb = MakeFooBar(3.4, 5);

because of the promotion and conversions rules for built-in numeric types. (C has never been really strongly typed)

In C++, what you want is achievable, though with the help of templates and static assertions:

template <typename Integer, typename Real>
FooBar MakeFooBar(Integer foo, Real bar) {
static_assert(std::is_same<Integer, int>::value, "foo should be of type int");
static_assert(std::is_same<Real, float>::value, "bar should be of type float");
return { foo, bar };
}

In C, you may name the parameters, but you'll never get further.

On the other hand, if all you want is named parameters, then you write a lot of cumbersome code:

struct FooBarMaker {
FooBarMaker(int f): _f(f) {}
FooBar Bar(float b) const { return FooBar(_f, b); }
int _f;
};

static FooBarMaker Foo(int f) { return FooBarMaker(f); }

// Usage
FooBar fb = Foo(5).Bar(3.4);

And you can pepper in type promotion protection if you like.

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

If you can, use GCC. Its C++ front.end understands C initializer syntax.

The way /* B */ is fine in C++ also the C++0x is going to extend the syntax so it is useful for C++ containers too. I do not understand why you call it bad style?

If you want to indicate parameters with names then you can use boost parameter library, but it may confuse someone unfamiliar with it.

Reordering struct members is like reordering function parameters, such refactoring may cause problems if you don't do it very carefully.

Extract the contants into functions that describe them (basic refactoring):

FooBar fb = { foo(), bar() };

I know that style is very close to the one you didn't want to use, but it enables easier replacement of the constant values and also explain them (thus not needing to edit comments), if they ever change that is.

Another thing you could do (since you are lazy) is to make the constructor inline, so you don't have to type as much (removing "Foobar::" and time spent switching between h and cpp file):

struct FooBar {
FooBar(int f, float b) : foo(f), bar(b) {}
int foo;
float bar;
};

Category:c# Views:0 Time:2011-05-30

Related post

  • Struct initialisation through macro overuse 2010-07-15

    I've got some structs to initialise, which would be tedious to do manually. I'd like to create a macro that will help me with it... but I'm not sure C preprocessor is good enough for this. I've got structs which represent menus. They consist of funct

  • C++ Struct initialisation problem 2010-09-30

    This c++ code is working fine , however memory validator says that I am using a deleted pointer in: grf->filePath = fname; Do you have any idea why ? Thank you. Dirloader.h // Other code class CDirLoader { public: struct TKnownGRF { std::string fi

  • trying to copy struct members to byte array in c 2009-01-27

    I am attempting to copy the members of a struct containing a mixture of ints, char's and arrays of chars into a byte array to send to a serial line. So far I have struct msg_on_send { char descriptor_msg[5]; int address; char space; char cmdmsg[5]; c

  • Why are C# structs immutable? 2010-09-20

    I was just curious to know why structs, strings etc are immutable? What is the reason for making them immutable and rest of the objects as mutable. What are the things that are considered to make an object immutable? Is there any difference on the wa

  • union initialisation 2011-05-28

    I'm attempting to globally initialise a union as in the following example: #include <cstdio> typedef union { char t[4]; int i; } a; enum { w = 5000, x, y, z }; a temp = {w}; int main() { printf("%d %d %d %d %d\n", temp.t[0],temp.t[1],temp.t[2],

  • Best way to handle memory allocation in C? 2009-04-06

    I think I've got a good grasp on how to handle memory in C++ but doing it in C is different I'm a bit off. In C++ I've got constructors and destructors, I've got the pretty straightforward new and delete and I know how to encapsulate it using RAII, u

  • How to check for NULL in c++? 2009-09-23

    Let say for example, I have a struct, and an array of the struct. What I want to do is to iterate through the array and check if any of the item is a null. I tried checking the item against NULL and (struct *) 0, that don't seem to work. Is there any

  • How do I specialize a templated class for data type classification? 2010-02-10

    We use boost - so using that library should be fine. But I've never managed to wrap my head around creating a set of templates which give you the right specialization for a whole class of data types, as opposed to specializing for a single data type

  • How to name Constructor Arguments when not using member var prefixes? 2011-03-09

    Certainly there is no one right way to do this, but I can't even think of any decent naming scheme, that's why I'm asking here. (So: While all answers will be subjective, they will be useful nevertheless!) The problem is as follows: For simple aggreg

  • Initializing a pointer to a structure 2011-06-09

    another linked question is segmentation fault while doing strcpy() I have a structure: struct thread_data{ char *incall[10]; int syscall arg_no; int client_socket; }; How do I initialize a pointer to a structure of type above as well as initialize th

  • object construction [c++] 2011-08-11

    I have this class: class A { B b; // snip. } This will work fine as long as B has a constructor which takes no arguments or the default constructor. However, If B needs to be constructed as B(x), how should the code be modified. One obvious way is to

  • Multi argument for implicit conversion 2011-09-08

    For a constructor with multiple arguments... For example: class C { public: C(int a=1, int b=2){ cout << a << ", " << b << "\n"; } } int main(){ C a(10), b = 20; } output: 10, 2 20, 2 How do I just assign value to the 2nd para

  • need to free a mutex? 2012-02-01

    I have a very simple (sample) C program as follows. I want to ensure I release any resources necessary so that valgrind does not complain. Do I need to free mutex1? Or do anything before the program terminates? Or is the mutex1 not allocate memory? 0

  • Avoiding Copy-Paste code initialising a series of SDL_Rects in a Struct 2012-02-13

    I've got a struct for defining the graphics of a feature in my 2D engine. In that, there are a series of SDL_Rects called "middle, left_edge, top_left_corner" etc. In part of my code, I'm initialising them off a series of arguments types into the scr

  • Declare and initialise an array of struct/class at the same time 2009-07-17

    1. I know that it is possible to initialise an array of structures in the declaration. For example: struct BusStruct { string registration_number; string route; }; struct BusStruct BusDepot[] = { { "ED3280", "70" }, { "ED3536", "73" }, { "FP6583", "7

  • How do I initialise a global array of structs in D? 2009-08-24

    In aid of my one-man quest to populate SO with D questions (=p), I've run into another problem; initialising an array of structs globally. Observe: struct A { int a; float b; } A[2] as; as[0] = {0, 0.0f}; as[1] = {5, 5.2f}; void main() {} Results in:

  • Why I initialise a struct in this way make my phone crashed? 2010-07-30

    I defined a struct: typedef struct myStruct{ int32 iMem1; int16 sMem2; int32 iMem3; }myStruct; And initialise it: void main(){ myStruct s1 = {0, 1, 0}; return 0; } When I run it in my phone, it crashed my phone. If I initialise it another way: void m

  • How can the initialisation of a struct be used as variable in a function call. ANSI-C Version 2010-12-30

    I am writing C89, C90, Ansi-C Code. One of my functions requires a struct as a parameter. I want to call the function with the initialisation of that struct rather tan creating a struct forst then passing it to the function. Here are some snippets wi

  • Struct member initialisation 2011-04-06

    Whilst reading through the DirectWrite source code I came across the following struct: /// <summary> /// Line breakpoint characteristics of a character. /// </summary> struct DWRITE_LINE_BREAKPOINT { /// <summary> /// Breaking condi

Copyright (C) dskims.com, All Rights Reserved.

processed in 0.107 (s). 11 q(s)