creating container classes that take a function template argument

Discussion in 'C++' started by Matt Fioravante, Feb 22, 2013.

  1. Suppose you wanted to write something like this:

    template <typename T, typename CMP=std::less<T> >
    class SortedVector : public std::vector<T> {
    //stuff
    }

    Whats the best way to "store" the CMP object?

    One could make a private data member CMP _cmp for example.

    However this seems to waste space when the comparison is a free function such
    as the the default std::less and it will store a function pointer to this
    method in _cmp. If you pass it a function, it should not use any storage to
    record this compile time constant information.

    However if you want to pass it a lambda or some other function object, you may
    have to store a copy of said object to retain its state.

    So basically what it boils down to is if the function object contains state,
    then store that state in the container. If it does not contain state, make the
    address of the function a compile time constant in the template argument.

    Whats the trick here to do this properly?
    Matt Fioravante, Feb 22, 2013
    #1
    1. Advertising

  2. Matt Fioravante <> wrote:
    > Suppose you wanted to write something like this:
    >
    > template <typename T, typename CMP=std::less<T> >
    > class SortedVector : public std::vector<T> {
    > //stuff
    > }
    >
    > Whats the best way to "store" the CMP object?
    >
    > One could make a private data member CMP _cmp for example.
    >
    > However this seems to waste space when the comparison is a free function such
    > as the the default std::less and it will store a function pointer to this
    > method in _cmp. If you pass it a function, it should not use any storage to
    > record this compile time constant information.


    I think you are confusing function objects, free functions and classes.
    CMP takes a _type_ not a function object, std::less is a class template,
    not a free function.
    A function object of type std::less<T> is an ordinary object with no data
    members. Objects normally don't store pointers to their member functions.

    To use std::less, you have to have an object anyway, because operator() is
    not static.

    In case of empty classes like std::less<T>, it might (or might not) be
    beneficial not to store the object in the class, but create a new one every
    time you use it.
    You can achieve this with a specialization of SortedVector for
    std::is_empty<CMP>::type.

    > However if you want to pass it a lambda or some other function object, you may
    > have to store a copy of said object to retain its state.


    You cannot "pass" a lambda as template parameter of kind "typename", only
    its type. The lambda itself has to be passed in the constructor. You have
    to manually instanciate the SortedVector template with the type of the
    lambda. Actually I don't know if that's even possible.

    > So basically what it boils down to is if the function object contains state,
    > then store that state in the container. If it does not contain state, make the
    > address of the function a compile time constant in the template argument.
    >
    > Whats the trick here to do this properly?


    Same confusion as above. You cannot pass arbitrary objects as template
    arguments, only types and a very limited range of primitive objects.

    Tobi
    Tobias Müller, Feb 22, 2013
    #2
    1. Advertising

  3. On Friday, February 22, 2013 2:45:22 AM UTC-5, Tobias Müller wrote:
    > In case of empty classes like std::less<T>, it might (or might not) be
    > beneficial not to store the object in the class, but create a new one every
    > time you use it.
    >
    > You can achieve this with a specialization of SortedVector for
    > std::is_empty<CMP>::type.


    One could also use private inheritance to take advantage of the empty base class optimization. That won't work if your comparison is an ordinary function pointer though.
    Matt Fioravante, Feb 22, 2013
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jim West
    Replies:
    3
    Views:
    758
    Jim West
    Oct 7, 2004
  2. Vijai Kalyan
    Replies:
    4
    Views:
    705
    Vijai Kalyan
    Nov 8, 2005
  3. nw
    Replies:
    0
    Views:
    314
  4. nguillot
    Replies:
    5
    Views:
    530
  5. avasilev
    Replies:
    4
    Views:
    576
    avasilev
    Dec 22, 2011
Loading...

Share This Page