Имеет ли это правило статического анализа C ++ смысл как есть?
Я реализую некоторые правила статического анализа C ++, и одно из них запрещает функции возвращать ссылку или указатель на ссылочный параметр функции, т. Е. Все они несовместимы:
int *f(int& x) { return &x; } // #1
const int *g(const int& x) { return &x; } // #2
int& h(int& x) { return x; } // #3
const int& m(const int& x) { return x; } // #4
Это объясняется тем, что «это поведение, определяемое реализацией, является ли ссылочный параметр временным объектом или ссылкой на параметр».
Я, однако, озадачен этим, потому что операторы потока в C ++ написаны таким образом, например
std::ostream& operator<<(std::ostream& os, const X& x) {
//...
return os;
}
Я думаю, что я вполне уверен, что потоковые операторы в C ++ обычно не демонстрируют поведение, определяемое реализацией, так что же происходит?
В соответствии с моим пониманием в настоящее время, я ожидаю, что № 1 и № 3 будут четко определены, поскольку временные ссылки не могут быть связаны с неконстантными ссылками,int& x
относится к реальному объекту, срок жизни которого выходит за рамки функции, поэтому возвращение указателя или ссылки на этот объект вполне допустимо. Я бы ожидал, что № 2 будет хитрым, потому что временное могло быть связано сconst int& x
в этом случае попытка получить его адрес показалась бы плохим планом. Я не уверен насчет # 4 - мое внутреннее чувство состоит в том, что это также потенциально изворотливо, но я не уверен. В частности, мне не ясно, что произойдет в следующем случае:
const int& m(const int& x) { return x; }
//...
const int& r = m(23);