Pass-by-Value in C 11: A Reassessment
In C 11, the introduction of rvalue references and move constructors has sparked a debate: should pass-by-value become the default for value types?
Origins of Pass-by-Reference
Historically, passing large objects by value in C was inefficient due to unnecessary copying. Reference parameters were preferred to avoid the costly duplication. However, references introduced complexities in ownership and memory management, particularly for heap-allocated objects.
The New Paradigm in C 11
With rvalue references and move constructors, it is now feasible to implement value types like std::vector and std::string that are inexpensive to pass by value. This raises the question: should pass-by-value be the new standard for these types?
Recommendations
According to Dave Abrahams, passing by value is recommended if a copy is required within the function. This allows the compiler to optimize the copy, as seen in the following example:
void foo(T t) { // ... }
This can be used flexibly to pass lvalues, prvalues, or xvalues:
T lval; foo(lval); // copy from lvalue foo(T {}); // (potential) move from prvalue foo(std::move(lval)); // (potential) move from xvalue
Exceptions
Pass-by-reference to const remains a reasonable option for certain scenarios where a copy is unnecessary or undesirable. In such cases, the following syntax can be employed:
class T { U u; V v; public: T(U u, V v) : u(std::move(u)) , v(std::move(v)) {} };
Conclusion
In C 11, pass-by-value is a compelling option for value types that require copying within functions. It simplifies parameter handling and allows for efficient move operations. However, pass-by-reference to const remains a suitable alternative in cases where a copy is not required.
The above is the detailed content of Should Pass-by-Value Be the Default for Value Types in C 11?. For more information, please follow other related articles on the PHP Chinese website!