Friday, July 08, 2005
C++ reference and initialization
A test function:
void test(string& s)
{
}
I can call this function with a string var:
string s("abc");
test(s);
But I cannot do this:
test(string("abc"));
But MS C/C++ compiler (Visual C++ Toolkit) compiles the above code with no problem.
I thought it was acceptable - but it is not.
However, if I declare the parameter to be const, like this:
void (const string& s)
Then I can do test(string("abc")) and EVEN test("abc")!
The reason:
When you declare a function like this...
void test(string& s);
You are telling the compiler "the test function is going to modify the parameters". That is to say, s is an output (or update) parameter.
When you call the function like this...
test(string("abc"));
...you are creating a temporary, anonymous string object, and passing it in to test. The compiler *KNOWS* (because you told it) that the string parameter is an output parameter. The compiler also knows that a temporary, anonymous used as an output parameter is 99% likely to be a mistake
-- why would you intentionally want to throw away the results of the routine? So likely is it to be a mistake, that it is actually disallowed by the ISO 14882 C++ standard -- it's a C++ programming error.
(Also, because of helpful conversions, you may get temporaries when you didn't expect them. That is the compelling reason that this situation is a disallowed. Your example is "obvious it is a temporary; it's explicit" ... but that's because it is a simple and straightforward example.)
When you declare the function...
void test(string const& s);
...you are telling the compiler that the parameter is an input only parameter, and hence temporaries are okay.
If you really don't like the parameter to be const, you could also do this...
void test(string s);
...and then the compiler *KNOWS* that the pass-by-value parameter is not an output parameter (so temporaries are okay) *AND* you can modify it within the routine.
void test(string& s)
{
}
I can call this function with a string var:
string s("abc");
test(s);
But I cannot do this:
test(string("abc"));
But MS C/C++ compiler (Visual C++ Toolkit) compiles the above code with no problem.
I thought it was acceptable - but it is not.
However, if I declare the parameter to be const, like this:
void (const string& s)
Then I can do test(string("abc")) and EVEN test("abc")!
The reason:
When you declare a function like this...
void test(string& s);
You are telling the compiler "the test function is going to modify the parameters". That is to say, s is an output (or update) parameter.
When you call the function like this...
test(string("abc"));
...you are creating a temporary, anonymous string object, and passing it in to test. The compiler *KNOWS* (because you told it) that the string parameter is an output parameter. The compiler also knows that a temporary, anonymous used as an output parameter is 99% likely to be a mistake
-- why would you intentionally want to throw away the results of the routine? So likely is it to be a mistake, that it is actually disallowed by the ISO 14882 C++ standard -- it's a C++ programming error.
(Also, because of helpful conversions, you may get temporaries when you didn't expect them. That is the compelling reason that this situation is a disallowed. Your example is "obvious it is a temporary; it's explicit" ... but that's because it is a simple and straightforward example.)
When you declare the function...
void test(string const& s);
...you are telling the compiler that the parameter is an input only parameter, and hence temporaries are okay.
If you really don't like the parameter to be const, you could also do this...
void test(string s);
...and then the compiler *KNOWS* that the pass-by-value parameter is not an output parameter (so temporaries are okay) *AND* you can modify it within the routine.