It's generally not a good idea to do that, except in the case of initializer lists where the language explicitly allows it.
Your specific problem I would solve in the following way:
1 2 3 4 5 6 7 8 9 10
class MyColor {
uint8_t r, g, b;
public:
MyColor( uint8_t r, uint8_t g, uint8_t b ) :
r( r ), g( g ), b( b ) {} // Shadowing data members here is allowed by the standard
void Set( uint8_t red, uint8_t green, uint8_t blue ) // Not allowed here
{ *this = MyColor( red, green, blue ); }
};
Duplicating variable names is a bad idea, even if it's technically legal in the language. All it does is lead to confusion as to which variable you meant to use.
It also tends to lead to bugs that are hard to find:
1 2 3
void MyColor::Set(uint8_t r, uint8_t g, uint8_t b) {
r = r;
}
That compiles just fine with no error or anything, but it obviously doesn't do what you'd expect. You'd be surprised how easy this mistake is to make.
I can live with that, but then it sounds like the OP has been playing with the idea and has fallen into the r = r; trap, so has found it is possibly not a good idea or maybe I was reading too much into it. ;0)
...except in the case of initializer lists where the language explicitly allows it.
for the language to explicitly allow it, it must be explicitly disallowed for else where and be in the standard. I am personally not aware of any such stipulation in the standard.
So I agree that it is not ideal, but I do not like the implication that it is not allowed.
It also tends to lead to bugs that are hard to find:
1 2 3
void MyColor::Set(uint8_t r, uint8_t g, uint8_t b) {
r = r;
}
I would hope that anyone writing the likes of r = r; would have alarm-bells ringing in there heads about ambiguity and do something about it.