vendredi 15 juillet 2022

Does rvalue reference parameter of built-in types make sense in terms of API design?

#include <cstdio>
#include <utility>

class RAIIFile {
    public:
        RAIIFile(std::FILE *&&f):file{f} { }
        ~RAIIFile(){/*std::fclose and handle error*/}
    private:
        std::FILE *file;
};

int main(void) {
    std::FILE *etc = std::fopen("/etc/fstab", "r");
    // RAIIFile f{etc}; // ill-formed program: cannot bind rvalue reference of type ‘FILE*&&’ to lvalue of type ‘FILE*’
    RAIIFile f{std::move(etc)}; // ok
}

In the snippet above, RAIIFile ctor takes a rvalue reference to raw pointer as parameter. The merit is, this would force the client to provide a rvalue expression argument, which forbids he/she from using a raw pointer on stack, or reminds he/she that the ownership of etc raw pointer has been transferred.

I understand move semantics and its primary purpose. My question is, as a library coder, whether designing public API that takes rvalue reference parameter of raw type (e.g. raw pointer) is a good practice.

It seems that c++ spec has taken a negative opinion, good example being ctor of std::unique_ptr taking pointer by-value.

Aucun commentaire:

Enregistrer un commentaire