Search code examples
c++shared-ptr

About std::unique_prt() and decltype()


What doesstd::unique_ptr<std::FILE, decltype(&close_file)> fp(std::fopen("demo.txt", "r"), &close_file); mean ?

I konw std::uqiue_ptr is an unique pointer. But i could not understand the entire expression.

Could anybody do me a favor?

  void close_file(std::FILE* fp) { std::fclose(fp); }

  std::cout << "Custom deleter demo\n";
  std::ofstream("demo.txt") << 'x'; // prepare the file to read
  {
      std::unique_ptr<std::FILE, decltype(&close_file)> fp(std::fopen("demo.txt", "r"),
                                                           &close_file);
      std::cout<<typeid((&close_file)).name()<<std::endl;
      if(fp) // fopen could have failed; in which case fp holds a null pointer
        std::cout << (char)std::fgetc(fp.get()) << '\n';
  }

Solution

  • Given void close_file(std::FILE* fp) { std::fclose(fp); }

    decltype(&close_file) is void(*)(stdFILE*) (function pointer).

    You can provide custom deleter to std::unique and it is what is done here:

    std::unique_ptr<std::FILE, decltype(&close_file)> fp(std::fopen("demo.txt", "r"),
                                                         &close_file);
    

    I think it is nicer to have better deleter though:

    struct file_closer
    {
        void operator()(std::FILE* fp) const { std::fclose(fp); }
    };
    

    or even

    template <auto* func>
    using Functor = std::integral_constant<decltype(func), func>;
    
    using file_closer = Functor<&std::fclose>;
    

    used as

    std::unique_ptr<std::FILE, file_closer> fp(std::fopen("demo.txt", "r"));