I get the warning from the title on Sun Studio 12.1 with the following snippet:
#include <vector>
std::vector<int> g()
{
std::vector<int> result;
result.push_back(5);
return result;
}
int main()
{
int b = g()[0]; // <- Warning in this 开发者_开发知识库line
return b;
}
Warning text is:
Warning: should not initialize a non-const reference with a temporary.
While I know that initialising a non-const reference with a temporary is a bad thing, I cannot see how that happens here. I know that [0]
returns a reference to the first element of the vector which itself is temporary, but I fail to see what the problem is.
Can somebody explain
- Why does to compiler complain?
- Is it a legitimate warning?
- If yes, what do I have to change?
- If no, how can I silence it elegantly?
No, it's not legitimate. The return value of g()
is a temporary, but it is not const - you just can't get a non-const reference to it. The non-const member operator[]
is perfectly valid to call here, and the double to integer conversion is just as safe.
This Sun compiler looks very weird, it doesn't seem legitimate at all to me. Ideone has no problem compiling it.
Regarding the silencing part:
std::vector<double> const tmp = g();
int b = tmp[0];
That is, introducing a named variable instead of leaving the temporary floating.
EDIT:
As suggested in comments, const-qualifying the return value might help.
std::vector<double> const g();
int main() {
int b = g()[0];
return b;
}
Yes, it does initialize a non-const reference with a temporary. But only conceptually during overload resolution and not actually. The compiler should not warn about it.
In overload resolution, the operator[]
has this function parameter signature
operator[](std::vector<int>&, std::vector<int>::size_type);
The first parameter will receive the temporary returned by g()
, but as said, that's fine and C++ makes specifically an exception for that reference, which is the so-called "implicit object parameter", so that overload resolution accepts the temporary argument.
精彩评论