uso tipos software resuelto practicos negocio especificacion ejemplos ejemplo documentacion diagrama detallado detallada casos caso c++ const-correctness

c++ - tipos - ¿Cuáles son los casos de uso para tener una función de retorno por valor de const para tipo no incorporado?



especificacion detallada de casos de uso (4)

Recientemente, he leído que tiene sentido cuando se devuelve por valor de una función para calificar el tipo de retorno const para tipos no incorporados, por ejemplo:

const Result operation() { //..do something.. return Result(..); }

Estoy luchando por comprender los beneficios de esto, una vez que el objeto ha sido devuelto, seguramente es la elección de quienes llaman para decidir si el objeto devuelto debe ser const?


Básicamente, hay un ligero problema de lenguaje aquí.

std::string func() { return "hai"; } func().push_back(''c''); // Perfectly valid, yet non-sensical

La devolución de valores constantes es un intento de evitar tal comportamiento. Sin embargo, en realidad, hace mucho más daño que bien, porque ahora que las referencias rvalue están aquí, vas a evitar la semántica de movimiento, lo cual es una mierda, y el comportamiento anterior probablemente se evitará mediante el uso juicioso de rvalue y lvalue *this sobrecarga Además, tendrías que ser un poco idiota para hacer esto de todos modos.


Como nadie ha señalado esto todavía, es bastante útil en objetos proxy, con casos de uso reales.

Imagine que está escribiendo un tipo de matrix y desea usarlo así:

Matrix<3, 3> matrix; Matrix<1, 3> rowVector; /* assign a row */ matrix[1] = rowVector;

Para hacer esto, devuelve un nuevo objeto proxy del operator[] . Al operar en una const Matrix , aún desea poder acceder a los datos a través del proxy, pero prohíbe el acceso de escritura. Esto se puede hacer volviendo por valor de const .

template<size_t Rows, size_t Cols> class Matrix { class RowProxy { Matrix& m; size_t row; /* ... operator= and operator[] */ }; RowProxy operator[](size_t row) { return RowProxy(*this, row); } const RowProxy operator[](size_t row) const { return RowProxy(*this, row); } // ^~~~ here the const is very useful and important };


No hay beneficio cuando regresas por valor. No tiene sentido.

La única diferencia es que evita que las personas lo usen como valor l:

class Foo { void bar(); }; const Foo foo(); int main() { foo().bar(); // Invalid }


Ocasionalmente es útil. Mira este ejemplo:

class I { public: I(int i) : value(i) {} void set(int i) { value = i; } I operator+(const I& rhs) { return I(value + rhs.value); } I& operator=(const I& rhs) { value = rhs.value; return *this; } private: int value; }; int main() { I a(2), b(3); (a + b) = 2; // ??? return 0; }

Tenga en cuenta que el valor devuelto por el operator+ se consideraría normalmente temporal. Pero está siendo claramente modificado. Eso no es exactamente deseado.

Si declara el tipo de retorno del operator+ como const I , no podrá compilarse.