Thread: Missing reference in function template?

  1. #16
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    I wanted the RAII wrapper to sit in place of the unmanaged resource without any extra syntax to use it.
    Actually, that is something I intended to bring up earlier. There is nothing wrong with implicit conversion operators, but unless you want weird syntax possibilities that are semantically meaningless you'll have to do the work of preventing them via `Boost' or some manually coded tool.

    Anyway, I had assumed this was part of a learning exercise. If that is your ultimate goal, as you are already using "C++1x" features, and this is a facility you intend to use in production you should build on `std::unique_ptr<???>' by containing an instance of it.

    Soma

  2. #17
    Registered User Inanna's Avatar
    Join Date
    May 2011
    Posts
    69
    Quote Originally Posted by phantomotap View Post
    Um... what? No. Very, very no.

    Code:
    unique_ptr<FILE, function<void(FILE*)> > in(fopen("test.cxx", "r"), ([](FILE * f){if(f){fclose(f);}}));
    Soma
    I learned something new, thank you. So now the problem with unique_ptr is just having to use get().

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Inanna View Post
    Yes, but why is the lambda signature's FILE* compatible with the function template's FILE*& when using a function instead of a function template is not? That was my question. It should fail to compile if the signatures do not match, but two C++0x compilers compile it without any warnings or errors.
    I assume that is, because as Soma says, std::function does some work "behind the scenes".
    I don't know more than that.

    The are two problems that brought me to my own RAII wrapper:
    • A direct lambda can not be used in place of fclose_deleter
      Code:
      // Will not compile!
      unique_ptr<FILE, [](FILE* fp) { if (fp) fclose(fp); }> in(fopen("test.txt", "r"));
    Of course not, as unique_ptr wants the type, not the object
    However, it is possible to do something like:
    Code:
    auto closer =  [](FILE* fp) { if (fp) fclose(fp); };
    unique_ptr<FILE,decltype(closer)> in(fopen("test.txt", "r"), closer);
    Or you can even abstract that with your own function:
    Code:
    template<typename ptr_t, closer_t> std::unique_ptr<ptr_t, closer_t> make_unique_ptr(ptr_t ptr, closer_t closer)
    {
        return std::unique_ptr<ptr_t, closer_t>(ptr, closer);
    }
    
    auto ptr = make_unique_ptr(fopen("test.txt", "r"), [](FILE* f) { if (f) fclose(f); });
    [*]To get the FILE* from a unique_ptr, I needed to call get(). I wanted the RAII wrapper to sit in place of the unmanaged resource without any extra syntax to use it.[/list]
    That's not a good idea unless you use a compiler that supports explicit conversion operators.

    Boost::ScopeExit did not even enter the running because it is ugly as sin.
    It's not that ugly.
    Besides, it is handy for the times when you want to do cleanup before exiting the scope without having to write a RAII wrapper for it.
    Last edited by Elysia; 05-29-2011 at 01:56 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #19
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Just trying something...

    Soma

  5. #20
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_O

    OOPS.

    Soma

  6. #21
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    std::function can wrap any function that has a compatible signature, not just an exact match. Compatible means that there are implicit conversions for all arguments and the return value. So, for example, you can do this:
    Code:
    char f(int i);
    std::function<int (char)> ff = f;
    because when calling, the char passed to the std::function call operator can be implicitly converted to int, and the char returned by f can be implicitly converted to the int that the std::function returns.

    Same for your original case, where the reference implicitly converts to a plain object.

    As for the dangling reference and temporary lifetime extension, that's a common mistake made by those who first hear of the feature.
    Code:
    struct StoresRef {
      const int& m_ref;
      StoresRef(const int&ref) : m_ref(ref) {}
    };
    void foo() {
      StoresRef sr(100);
      std::cout << sr.m_ref; // error!
    }
    The mistake is to assume that since StoresRef holds a reference to the int passed to the constructor, the lifetime of the temporary int is extended with the StoresRef object. But the lifetime of a temporary is only extended to the lifetime of the object it is initially bound to, and that's not sr.m_ref, but the ref parameter to StoresRef's constructor! This reference goes out of scope as the constructor returns, which is actually before the temporary itself disappears (at the end of the full-expression, i.e. at the semicolon). The temporary is not kept alive beyond the statement, so in the std::cout, m_ref is already dangling.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 01-30-2011, 04:28 PM
  2. undefined reference to template function
    By Elkvis in forum C++ Programming
    Replies: 5
    Last Post: 09-02-2009, 08:13 AM
  3. object missing in reference to `Window::border'
    By leeor_net in forum C++ Programming
    Replies: 7
    Last Post: 06-02-2008, 03:13 PM
  4. Specialising a member function with a template template parameter
    By the4thamigo_uk in forum C++ Programming
    Replies: 10
    Last Post: 10-12-2007, 04:37 AM
  5. missing template parameters? help!
    By Lateralus in forum C++ Programming
    Replies: 1
    Last Post: 01-29-2006, 11:25 AM