STL map containing pointer_to_binary_function

G

Glennmac

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
 
V

Victor Bazarov

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
 
B

Barry

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
 
G

Glennmac

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
 
B

Barry

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
 
B

Barry

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());
}
 
G

Glennmac

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

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>;

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());

}
 
B

Barry

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;
}
}
 
T

Thomas J. Gritzan

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;
 
B

Barry

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top