STL map containing pointer_to_binary_function

Discussion in 'C++' started by Glennmac@gmail.com, Aug 28, 2007.

  1. Guest

    Hi All,

    I am beating my head against the wall trying to figure out how to make
    this work.

    I have a map which contains a string as the key and I want the data to
    be a pointer_to_binary_function, but at the time of map definition, I
    don't know the types. So really the map contains a templatized
    pointer_to_binary_function. When I actually add to the map is where I
    know the types of the binary function.

    Adding to the map:

    mMap.insert("test", ptr_fun(not_equal_to<int>));

    Fails with: error: expected promary-expression before ')' token

    I am at a loss here.

    Thanks

    Glenn
     
    , Aug 28, 2007
    #1
    1. Advertising

  2. wrote:
    > I am beating my head against the wall trying to figure out how to make
    > this work.
    >
    > I have a map which contains a string as the key and I want the data to
    > be a pointer_to_binary_function, but at the time of map definition, I
    > don't know the types.


    Then you don't have an object. There is no way around it, if you want
    to define an object, you need to give it a concrete type.

    > So really the map contains a templatized
    > pointer_to_binary_function.


    That's nonsense, sorry.

    > When I actually add to the map is where I
    > know the types of the binary function.


    If you know it when you want to add, you should be able to know it
    when you construct your map. It all happens while you're coding.

    > Adding to the map:
    >
    > mMap.insert("test", ptr_fun(not_equal_to<int>));
    >
    > Fails with: error: expected promary-expression before ')' token
    >
    > I am at a loss here.


    One like of code is *not enough* to understand how to get you back on
    track. Please explain the problem you're trying to solve.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 28, 2007
    #2
    1. Advertising

  3. Barry Guest

    wrote:
    > Hi All,
    >
    > I am beating my head against the wall trying to figure out how to make
    > this work.
    >
    > I have a map which contains a string as the key and I want the data to
    > be a pointer_to_binary_function, but at the time of map definition, I
    > don't know the types. So really the map contains a templatized
    > pointer_to_binary_function. When I actually add to the map is where I
    > know the types of the binary function.
    >
    > Adding to the map:
    >
    > mMap.insert("test", ptr_fun(not_equal_to<int>));


    ptr_fun adapts a free function, but not_equal_to is template functor class

    >
    > Fails with: error: expected promary-expression before ')' token
    >
    > I am at a loss here.
    >
    > Thanks
    >
    > Glenn
    >



    --
    Thanks
    Barry
     
    Barry, Aug 29, 2007
    #3
  4. Guest

    Thanks for the info.

    Let me clearify my goal, I want a map to contain a string as the key
    and a function pointer template as the data. Meaning, I want to insert
    into the map the following things:

    map["test"] = equal_to<string>; // or pointers to the
    binary_function....
    map["test1"] = equal_to<int>;
    map["test2"] = less<double>;

    etc...

    I know the base template for all those functors is the binary_function
    template.

    Is it possible to have a map where the data is a binary_function
    template?

    Thanks

    Glenn



    On Aug 29, 2:58 am, Barry <> wrote:
    > wrote:
    > > Hi All,

    >
    > > I am beating my head against the wall trying to figure out how to make
    > > this work.

    >
    > > I have a map which contains a string as the key and I want the data to
    > > be a pointer_to_binary_function, but at the time of map definition, I
    > > don't know the types. So really the map contains a templatized
    > > pointer_to_binary_function. When I actually add to the map is where I
    > > know the types of the binary function.

    >
    > > Adding to the map:

    >
    > > mMap.insert("test", ptr_fun(not_equal_to<int>));

    >
    > ptr_fun adapts a free function, but not_equal_to is template functor class
    >
    >
    >
    > > Fails with: error: expected promary-expression before ')' token

    >
    > > I am at a loss here.

    >
    > > Thanks

    >
    > > Glenn

    >
    > --
    > Thanks
    > Barry
     
    , Aug 29, 2007
    #4
  5. Barry Guest

    wrote:
    > Thanks for the info.
    >
    > Let me clearify my goal, I want a map to contain a string as the key
    > and a function pointer template as the data. Meaning, I want to insert
    > into the map the following things:
    >
    > map["test"] = equal_to<string>; // or pointers to the
    > binary_function....
    > map["test1"] = equal_to<int>;
    > map["test2"] = less<double>;
    >
    > etc...
    >
    > I know the base template for all those functors is the binary_function
    > template.
    >
    > Is it possible to have a map where the data is a binary_function
    > template?
    >
    > Thanks
    >


    You can't do that, because

    1.
    std::binary_function<ArgumentType, bool> are various types if
    ArgumentType varies, then the pair type used for map is dependent on
    ArgumentType.

    2.
    less<T> or greater<T> inherits from binary_function, which is not
    virtual a class type, operator() is not virtual. so there's no
    conversion between them (less<T> <==> binary_function<T, U>, greater<T>
    <==> binary_function), and the right operator() can't be called



    --
    Thanks
    Barry
     
    Barry, Aug 29, 2007
    #5
  6. Barry Guest

    wrote:
    > Thanks for the info.
    >
    > Let me clearify my goal, I want a map to contain a string as the key
    > and a function pointer template as the data. Meaning, I want to insert
    > into the map the following things:
    >
    > map["test"] = equal_to<string>; // or pointers to the
    > binary_function....
    > map["test1"] = equal_to<int>;
    > map["test2"] = less<double>;
    >
    > etc...
    >
    > I know the base template for all those functors is the binary_function
    > template.
    >
    > Is it possible to have a map where the data is a binary_function
    > template?


    use boost::any


    #include <map>
    #include <string>
    #include <functional>
    #include <algorithm>
    #include <iostream>

    #include <boost/any.hpp>

    using namespace std;
    using namespace boost;


    struct FunctorDispatcher
    {
    void operator() (pair<string, boost::any> const& p) const {
    if (p.first == "less<int>")
    {
    less<int> const* pFnct
    = boost::any_cast<less<int> >(&(p.second));
    if ((*pFnct)(1, 2))
    cout << "true" << endl;
    }
    else if (p.first == "equal_to<string>")
    {
    equal_to<string> const* pFnct
    = boost::any_cast<equal_to<std::string> >(&(p.second));
    if ((*pFnct)("1", "1"))
    cout << "true" << endl;
    }
    }
    };

    int main()
    {

    map<string, any> functorMap;

    functorMap.insert(make_pair("less<int>", less<int>()));
    functorMap.insert(make_pair("equal_to<string>", equal_to<string>()));

    for_each(functorMap.begin(), functorMap.end(), FunctorDispatcher());
    }

    --
    Thanks
    Barry
     
    Barry, Aug 29, 2007
    #6
  7. Guest

    Barry,

    Thanks for the help. I have been working on a different method to do
    this, but have hit the same results.

    I have created a base class:

    template <typename T>
    class base {
    public:
    base(T eval) :
    mValue(eval)
    {};

    virtual ~base() {};

    bool run(const string &actualValue) {
    runInternal(mValue, actualValue);
    }

    protected:
    virtual bool runInternal(int v1, const string &v2) = 0;
    virtual bool runInternal(const string &v1, const string &v2) = 0;

    protected:
    T mValue;
    };


    template <typename T>
    class d1 : public base<T> {
    public:
    d1(T eval) :
    base<T>(eval)
    {};

    private:
    bool runInternal(int v1, const string &v2) {
    // convert string to int
    return v1 == v2;
    };

    bool runInternal(const string &v1, const string &v2) {
    return v1 == v2;
    };
    };

    As I am sure you can see, I can not create a map<string, base *>
    because base needs a type at that point. Can I somehow use a template
    function in the class and not a complete template class?

    Basically I need to have a map of functions, classes whatever that
    test <, > and == of a known value and actual value. They can be
    strings, int, and doubles. Is this possible?

    Thanks

    Glenn

    On Aug 29, 10:28 am, Barry <> wrote:
    > wrote:
    > > Thanks for the info.

    >
    > > Let me clearify my goal, I want a map to contain a string as the key
    > > and a function pointer template as the data. Meaning, I want to insert
    > > into the map the following things:

    >
    > > map["test"] = equal_to<string>; // or pointers to the
    > > binary_function....
    > > map["test1"] = equal_to<int>;
    > > map["test2"] = less<double>;

    >
    > > etc...

    >
    > > I know the base template for all those functors is the binary_function
    > > template.

    >
    > > Is it possible to have a map where the data is a binary_function
    > > template?

    >
    > use boost::any
    >
    > #include <map>
    > #include <string>
    > #include <functional>
    > #include <algorithm>
    > #include <iostream>
    >
    > #include <boost/any.hpp>
    >
    > using namespace std;
    > using namespace boost;
    >
    > struct FunctorDispatcher
    > {
    > void operator() (pair<string, boost::any> const& p) const {
    > if (p.first == "less<int>")
    > {
    > less<int> const* pFnct
    > = boost::any_cast<less<int> >(&(p.second));
    > if ((*pFnct)(1, 2))
    > cout << "true" << endl;
    > }
    > else if (p.first == "equal_to<string>")
    > {
    > equal_to<string> const* pFnct
    > = boost::any_cast<equal_to<std::string> >(&(p.second));
    > if ((*pFnct)("1", "1"))
    > cout << "true" << endl;
    > }
    > }
    >
    > };
    >
    > int main()
    > {
    >
    > map<string, any> functorMap;
    >
    > functorMap.insert(make_pair("less<int>", less<int>()));
    > functorMap.insert(make_pair("equal_to<string>", equal_to<string>()));
    >
    > for_each(functorMap.begin(), functorMap.end(), FunctorDispatcher());
    >
    > }
    >
    > --
    > Thanks
    > Barry
     
    , Aug 29, 2007
    #7
  8. Barry Guest

    wrote:
    > Barry,
    >
    > Thanks for the help. I have been working on a different method to do
    > this, but have hit the same results.
    >
    > I have created a base class:
    >
    > template <typename T>
    > class base {
    > public:
    > base(T eval) :
    > mValue(eval)
    > {};
    >
    > virtual ~base() {};
    >
    > bool run(const string &actualValue) {
    > runInternal(mValue, actualValue);
    > }
    >
    > protected:
    > virtual bool runInternal(int v1, const string &v2) = 0;
    > virtual bool runInternal(const string &v1, const string &v2) = 0;
    >
    > protected:
    > T mValue;
    > };
    >
    >
    > template <typename T>
    > class d1 : public base<T> {
    > public:
    > d1(T eval) :
    > base<T>(eval)
    > {};
    >
    > private:
    > bool runInternal(int v1, const string &v2) {
    > // convert string to int
    > return v1 == v2;
    > };
    >
    > bool runInternal(const string &v1, const string &v2) {
    > return v1 == v2;
    > };
    > };
    >
    > As I am sure you can see, I can not create a map<string, base *>
    > because base needs a type at that point. Can I somehow use a template
    > function in the class and not a complete template class?
    >
    > Basically I need to have a map of functions, classes whatever that
    > test <, > and == of a known value and actual value. They can be
    > strings, int, and doubles. Is this possible?
    >


    So don't have
    template <class T>
    class Base;

    instead have
    class Base {
    public:
    virutal bool Compare(boost::any arg0, boost::any arg2) = 0;
    };

    template <class T, U>
    class Child : public Base
    {
    // override Compare
    // boost::any_cast to T and U with arg0 and arg1, then do the compare
    };

    the code can be like this:

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <string>
    #include <sstream>

    #include <boost/any.hpp>


    class Base {
    public:
    virtual bool Compare(boost::any const& arg0, boost::any const& arg1)
    {
    return false;
    }

    virtual bool Compare(boost::any const& arg)
    {
    return false;
    }

    virtual ~Base () { }
    };

    template <class T, class U>
    class Child1 : public Base
    {
    public:
    Child1(U arg1) : arg1_(arg1) {}

    protected:
    virtual bool Compare(boost::any const& arg0)
    {
    if (T const* pT = boost::any_cast<T>(&arg0))
    {
    if ((*pT) == arg1_) {
    std::cout << "true" << std::endl;
    return true;
    }
    }

    return false;

    }
    private:
    U arg1_;
    };


    template <class T, class U>
    class Child2 : public Base
    {
    protected:
    virtual bool Compare(boost::any const& arg0, boost::any const& arg1)
    {
    T const* pT = boost::any_cast<T>(&arg0);
    U const* pU = boost::any_cast<U>(&arg1);

    if (pT && pU)
    {
    if ((*pT) == (*pU)) {
    std::cout << "true" << std::endl;
    return true;
    }
    }

    return false;
    }
    };

    bool operator== (std::string const& lhs, int rhs)
    {
    std::eek:stringstream oss;
    oss << rhs;
    return lhs == oss.str();
    }

    bool operator== (int lhs, std::string const& rhs)
    {
    std::eek:stringstream oss;
    oss << lhs;
    return rhs == oss.str();
    }

    int main()
    {
    std::map<std::string, Base*> Map;
    Map["test1"] = new Child1<int, int>(10);
    Map["test2"] = new Child1<int, std::string>("100");
    Map["test3"] = new Child1<std::string, int>(100);

    Map["test1"]->Compare(10);
    Map["test2"]->Compare(100);
    Map["test3"]->Compare(std::string("100"));

    Map["test4"] = new Child2<int, int>();
    Map["test5"] = new Child2<int, std::string>();
    Map["test6"] = new Child2<std::string, int>();

    Map["test4"]->Compare(10, 10);
    Map["test5"]->Compare(100, std::string("100"));
    Map["test6"]->Compare(std::string("100"), 100);

    for (std::map<std::string, Base*>::iterator it = Map.begin();
    it != Map.end(); ++it)
    {
    delete it->second;
    }
    }
     
    Barry, Aug 30, 2007
    #8
  9. schrieb:
    > Basically I need to have a map of functions, classes whatever that
    > test <, > and == of a known value and actual value. They can be
    > strings, int, and doubles. Is this possible?


    Take a look at boost.variant and boost.function:

    http://www.boost.org/doc/html/variant.html
    http://www.boost.org/doc/html/function.html

    With boost.variant you can define visitors that compare two variant
    instances. A variant can store a set of types like:

    typedef boost::variant<std::string, int, double> myVariant;

    --
    Thomas
    http://www.netmeister.org/news/learn2quote.html
    The pedants here will shout "int main(void)" but I'll just whisper it.
    --Bob Wightman in comp.lang.c
     
    Thomas J. Gritzan, Sep 3, 2007
    #9
  10. Barry Guest

    Thomas J. Gritzan wrote:
    > schrieb:
    >> Basically I need to have a map of functions, classes whatever that
    >> test <, > and == of a known value and actual value. They can be
    >> strings, int, and doubles. Is this possible?

    >
    > Take a look at boost.variant and boost.function:
    >
    > http://www.boost.org/doc/html/variant.html
    > http://www.boost.org/doc/html/function.html
    >
    > With boost.variant you can define visitors that compare two variant
    > instances. A variant can store a set of types like:
    >
    > typedef boost::variant<std::string, int, double> myVariant;
    >

    With Boost.Variant, the operator() argument can only be one

    It it right?

    So it can't deal the Compare(Type1 arg0, Type2 arg1) case

    --
    Thanks
    Barry
     
    Barry, Sep 3, 2007
    #10
  11. Barry schrieb:
    > Thomas J. Gritzan wrote:
    >> schrieb:
    >>> Basically I need to have a map of functions, classes whatever that
    >>> test <, > and == of a known value and actual value. They can be
    >>> strings, int, and doubles. Is this possible?

    >>
    >> Take a look at boost.variant and boost.function:
    >>
    >> http://www.boost.org/doc/html/variant.html
    >> http://www.boost.org/doc/html/function.html
    >>
    >> With boost.variant you can define visitors that compare two variant
    >> instances. A variant can store a set of types like:
    >>
    >> typedef boost::variant<std::string, int, double> myVariant;
    >>

    > With Boost.Variant, the operator() argument can only be one
    >
    > It it right?
    >
    > So it can't deal the Compare(Type1 arg0, Type2 arg1) case


    You can have binary visitors:
    http://www.boost.org/doc/html/variant/tutorial.html#variant.tutorial.binary-visitation

    You can even use a template, so that you don't have to write a function for
    every possible combination.

    --
    Thomas
    http://www.netmeister.org/news/learn2quote.html
    To iterate is human, to recurse divine.
    -L. Peter Deutsch
     
    Thomas J. Gritzan, Sep 3, 2007
    #11
    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. Koen
    Replies:
    1
    Views:
    503
  2. Marcus
    Replies:
    2
    Views:
    592
    Marcus
    Dec 9, 2005
  3. Replies:
    2
    Views:
    556
    klaus hoffmann
    Feb 22, 2006
  4. kl
    Replies:
    7
    Views:
    1,291
    James Kanze
    Jan 1, 2008
  5. Luca Risolia

    STL map to STL vector

    Luca Risolia, Jan 13, 2014, in forum: C++
    Replies:
    32
    Views:
    375
    Seungbeom Kim
    Jan 18, 2014
Loading...

Share This Page