Michael
Michael

Reputation: 958

Returning a moved parameter on failure

Is it an acceptable pattern to return a moved function parameter in case some kind of problem occurred? For example when trying to store data in a database, but validation failed and the data handle should be returned.

class Database {
    using data_ptr = std::unique_ptr<std::vector<int>>;
public:
    [[nodiscard]] std::expected<void, data_ptr>
    validate_and_store(data_ptr&& data) {
        if(!validate_data(data)) {
            return std::unexpected(std::move(data));
        }
        m_data = std::move(data);
        return {};
    }
private:
    data_ptr m_data;
    static bool validate_data(data_ptr& data) {return data->size() < 6;}
};

The r-value parameter of validate_and_store should indicate that ownership of the data is usually transferred, but in an unexpected case, a handle to the that data is returned.

So a consumer could use this as

Database db;
auto data_owner = get_big_data_from_somewhere();
auto db_info = db.validate_and_store(std::move(data_owner));
if(!db_info) {
    data_owner = std::move(db_info.error());
}

Is there a better (or best) practice on how to intend giving up ownership on success, but returning it to the caller if a problem arises? Of course, one could just use a (non-const) reference here and just check for nullptr afterwards, but that doesn't seem to show the intended behavior in a clear way.

Upvotes: 2

Views: 80

Answers (0)

Related Questions