7

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 aggregate structs, we do not use member var prefixes.

struct Info {
  int x;
  string s;
  size_t z;

  Info()
  : x(-1)
  , s()
  , z(0)
  { }
};

It is nevertheless sometimes useful to provide an initializer ctor to initialize the struct, however - I cannot come up with a decent naming scheme for the parameters when the most natural names for them are already taken up by the member variables themselves:

struct Info {
  int x;
  string s;
  size_t z;

  Info(int x?, string s?, size_t z?)
  : x(x?)
  , s(s?)
  , z(z?)
  { }
};

What are other people using in this situation?

Wolf
  • 9,679
  • 7
  • 62
  • 108
Martin Ba
  • 37,187
  • 33
  • 183
  • 337
  • 1
    What i've seen (mainly from Java devs) is to use the same name. Then in the constructor do `this->s = s`, etc. – Juancho Mar 09 '11 at 13:21
  • 1
    @Juancho: Yeah, except that this unfortunately won't work with initializer lists in constructors. – Frerich Raabe Mar 09 '11 at 13:25
  • 4
    @Frerich Raabe - It works even better with initializer lists. – Chris Lutz Mar 09 '11 at 13:28
  • possible duplicate of [Parameters Naming for Constructor](http://stackoverflow.com/questions/1780933/parameters-naming-for-constructor) – Suma Mar 09 '11 at 13:35
  • @Chris: How does explicitely addressing the member variable using `this->` work better with initializer lists? – Frerich Raabe Mar 09 '11 at 15:13
  • 1
    @Frerich - You don't have to for initializer lists. `s(s)` does what you want (but maybe not initially expect) it to do. Thus, it works "better" (you don't have to use `this->` to disambiguate). – Chris Lutz Mar 09 '11 at 15:15
  • I think a [combination of both strategies](https://stackoverflow.com/a/46035594/2932052) (same names, prefixes) is sometimes necessary, depending on whether the initialization can take place in the initializer list... – Wolf Sep 04 '17 at 12:56
  • I slightly reworded the question, I hope it's okay for you: Here we talk of [parameter names](https://stackoverflow.com/a/156787/2932052) ("arguments" are used in calls) – Wolf Sep 04 '17 at 12:59

8 Answers8

12

Use the same names - they don't collide.

"During the lookup for a name used ... in the expression of a mem-initializer for a constructor (12.6.2), the function parameter names are visible and hide the names of entities declared in the block, class or namespace scopes containing the function declaration." 3.4.1 C++ 2003

fizzer
  • 13,551
  • 9
  • 39
  • 61
  • This is an old topic, but we should think about this again. `clang++` comes up with a warning (when compiling with -Wshadow) and this seems to be for a reason. – UniversE Dec 27 '16 at 16:22
11

Why invent pre/postfixes? I just use the same name. C++ is designed for that to work.

struct Info {
  int x;
  string s;
  size_t z;

  Info(int x, string s, size_t z)
  : x(x)
  , s(s)
  , z(z)
  { }
};

It's straight forward.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 4
    For the same reason you use extra parentheses in boolean expressions: because most people (including me) can't remember how the language works exactly in some cases. It avoids the "mental speed bump" when reading the code. – Frerich Raabe Mar 09 '11 at 13:23
  • 3
    @Frerich, the question was suggestive. Unlike remembering the 20+ precedence rules, which I can't see to be useful, remembering this rule has proven to be quite useful to me. If you have an empty body and only the initializer list, you don't have to worry about anything else. Isn't it great? – Johannes Schaub - litb Mar 09 '11 at 13:24
  • +1 : Oh my. That's certainly confusing to read :-) - but it certainly is a valid option :-) – Martin Ba Mar 09 '11 at 13:41
6

I tend to use "a" prefix - as in "a whatever".

Info(int aX, string const & aS, size_t aZ);


struct Time {
  Time(time_t aUnixTime) : UnixTime(aUnixTime) {}
  time_t UnixTime;
};
Erik
  • 88,732
  • 13
  • 198
  • 189
  • 1
    Maybe meanwhile you changed your mind, but isn't it [cumbersome to capitalize the the variable names](https://stackoverflow.com/a/46035594/2932052)? – Wolf Sep 04 '17 at 11:01
3

Something I've seen around here is using trailing underscores for constructor arguments, e.g.:

struct Info {
  int i, j;
  Info( int i_, int j_ ) : i( i_ ), j( j_ ) { }
};
Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
3

I believe as long as you're using the initialization list, you can use the same names:

struct Info {
  int x;
  string s;
  size_t z;

  Info(int x, string s, size_t z) : x(x) , s(s) , z(z)
  { }
};

If you had to do some work to initialize a field, you could still get away with using the same names, but it would be a little less convenient:

struct Example {
  char *c;
  size_t l;

  Example(char *c, size_t l) : l(l), c(new char[l])
  {
      // in the block c is the parameter and this->c is the member
      std::copy(c, c + l, this->c);
  }
};
Chris Lutz
  • 73,191
  • 16
  • 130
  • 183
3

I am using this:

struct Info {
  int x;
  string s;
  size_t z;

  Info(int x, string s, size_t z)
  : x(x)
  , s(s)
  , z(z)
  { }
};

It may be a bit surprise, but this is perfectly legal.

See also:

Can I use identical names for fields and constructor parameters?

Parameters Naming for Constructor

Community
  • 1
  • 1
Suma
  • 33,181
  • 16
  • 123
  • 191
1

You can use parameter name identical to member names (but some find it confusing).

I've seen the use of prefix/suffix for members (_, m, my_ are popular in which case there is no conflict with parameters) or for parameters (a prefix of p is the most popular for that use in my experience).

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
0

In cases where members are simply set to the values of the corresponding parameters, use the initializer list. Here using the same name for member variable and parameter is absolutely safe. If you cannot simply assign values, but have to call functions, it's vital to make the names of members and parameters easy to distinguish, but also easy to make the relation visible, here a prefix or postfix is a good option.

Erik's answer suggests the prefix a, but I find the extra-work to change the first letter or the original name to upper case for getting the parameter name extremely annoying, it prevents simply using copy&paste (Letting it unchanged is not an option because you don't want to observe potential changes in meaning by adding the prefix for each single case).

For cases where the initializer list cannot be used, I came up with a_ that can be used as a prefix before the original name.

struct Info {
    int value;
    char description[MAX_DESCRIPTION_SIZE];

    Info(int value, char* a_description)
    : value(value)
    {
        someSafeCopy(description, a_description);
    }
};
Wolf
  • 9,679
  • 7
  • 62
  • 108