views:

105

answers:

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.

+5  A: 

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;
}
Peter Alexander
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
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
A: 

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
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
A: 

Don't use parameters that clash with member variables.
It may be OK at the language level, but it just makes it hard to read for humans.

The WHOLE point is to write code that is easy to read fro humans. The compiler will do just fine

template<typename T>
struct Foo 
{ 
   explicit Foo(T x_) // Wow hat a difference a single character does for readability.
       :x(x_)  
   {} 

    T x; 
};
Martin York