3

I have a simple object that holds some [public] data.

I want to keep my interface clean, so I don't want to pre-/post- fix anything to the names of the publically accessible variables nor to the names of my function arguments.

That said, I ended up doing something like this:

template<typename T> struct Foo
{
  explicit Foo(T x) : x(x) // This [i.e., x(x)] seems to be doing the "Right Thing", but is this well defined?
  {/*            ^ 
       No pre-/post- fixing.
   */
  }

  T x; // No pre-/post- fixing.
};

Just to reiterate: All I'm asking is whether this is well defined behavior. Not whether I should or shouldn't be doing this...

Thanks.

eciDive
  • 33
  • 3
  • This same question was asked about a day ago; sorry I don't have a link. The answer appeared to be that yes, it was well defined. – Mark Ransom Feb 02 '10 at 03:44
  • Thanks, I guess I missed it in my search. I'll accept Poita_'s answer, then. – eciDive Feb 02 '10 at 03:48
  • I would not use just becaue you have to ask the question. The fact that it is not esay to read means that a maintainer will come along in a year and say hay that does not look write and either fix it or spend a dat making sure it works. A simpel rule dont write code that requires you have to ask a question about weather it is valid. – Martin York Feb 02 '10 at 06:58

2 Answers2

7

Yes, that's fine, and perfectly standard.

Local variables always come first in a name lookup, but the x(...) in an initialization list can obviously only refer to member variables [edit:or a base class].

If you didn't use the initialization list, you would have to write:

explicit Foo(T x)
{
    this->x = x;
}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • Whooooo. Thats not the same. Here you are default contructing then using the assignment operator. That is definately not ideal especially of T is not simple. – Martin York Feb 02 '10 at 06:56
  • 1
    It is not the same from the point of view of the actual execution, but it is a good example on how the name lookup is performed: within the constructor body the local variable hides the member and thus the member must be fully qualified, while in the initialization list, the initialized (lack a better name) names must be subobjects of the current class and don't require the explicit this. I have always found interesting how in `x(x)` the first and second `x` are resolved differently, even if it makes complete sense. – David Rodríguez - dribeas Feb 02 '10 at 08:27
1

Specifically for the initializer list of a ctor, it's well-defined behavior -- since you can only initialize a member or base class, there's no ambiguity between one of those and the name of a parameter.

Under almost any other circumstance, however, you'll create an ambiguity. In particular, your title simply refers to "function" -- and for any function other than the ctor, this won't work. Even inside the body of the ctor, it won't work -- the "special" treatment is purely within the initializer list of a ctor.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Thanks, I'm aware of the ambiguity and the need for "this->"-access. Upon reflection, I think I should have come up with a better title. ;) – eciDive Feb 02 '10 at 03:56