Arguments Passing in C++

Arguments Passing in C++

Instance Variable is Reference Type

class OrderConsumer {
    std::string& output_csv_;
public:
    explicit OrderConsumer(const std::string& output_csv) : output_csv_(output_csv)) {
    }
};

Note that you need to ensure that the lifetime of the output_csv argument passed to the constructor is longer than the lifetime of the OrderConsumer instance, otherwise you will have a dangling reference.

Instance Variable is Value Type

class OrderConsumer {
    std::string output_csv_;
public:
    explicit OrderConsumer(std::string output_csv) : output_csv_(std::move(output_csv)) {
    }
};

versus

Option 1: Pass by value and move

Value is copied into the constructor parameter, and then moved into the member variable.

  • Simpler code, as it doesn't require explicit move semantics in the constructor.

  • If the caller passes a lvalue, it will be copied into the constructor parameter, which can be inefficient for large strings.

  • If the caller passes a rvalue, it will be moved into the constructor parameter, which is efficient, but the caller must be aware of this behavior

Option 2: Pass by const reference

Value is passed by const reference, and then copied into the member variable.

  • More efficient for lvalues, as it avoids unnecessary copying.

  • If the caller passes a rvalue, it will be copied into the constructor parameter, which can be inefficient for large strings, and the caller must be aware that they are passing a rvalue.

  • Requires the caller to explicitly use std::move if they want to pass an rvalue, which can lead to errors if they forget to do so.

Conclusion

Option 1 win, because it is more flexible and can handle both lvalues and rvalues efficiently without requiring the caller to be aware of the underlying implementation details. It also simplifies the code by avoiding the need for explicit move semantics in the constructor.

Last updated