how to combine 2 independent boost::bind() into one boost::function? - c++

I have 2 functions f() and g(). I want to call them in order every time. Can I get a boost::function to do this?
E.g. something like:
boost::function functor = boost::bind( boost::bind(f), boost::bind(g) );
Extend this further, say it takes arguments, then what I need is a chain of responsibility. Each node does something with arguments, then followed by next node of chain.
How do I do that?
Update Thanks for Seth Carnegie's comments.
I think what I really want is how to construct a chain of responsibility into a single boost::function, each node of chain can be constructed by using boost::bind().

Have you considered using boost::signal ?
With boost::signal you can connect multiple function calls into one.
#include <boost/signal.hpp>
#include <iostream>
void f()
{
std::cout << " Hello" << std::flush;
}
void g()
{
std::cout << " World" << std::endl;
}
int main()
{
boost::signal<void ()> s;
s.connect(f);
s.connect(g);
s();
}

Why not something like this?
#include <functional>
template <typename FirstFunctor, typename SecondFunctor>
void chainFunctionImpl(FirstFunctor first, SecondFunctor second)
{
first();
second();
}
template <typename FirstFunctor, typename SecondFunctor>
std::function<void(void)> chainFunction(FirstFunctor first, SecondFunctor second)
{
return std::bind(chainFunctionImpl<FirstFunctor,SecondFunctor>,first,second);
}
Use should be relatively simple, just binding the functions in sequence, then calling the result. Theoretically any length of functions could be chained up.
Note that is theoretically possible to do this with passing an argument down the chain as well, but that level of template foo is way beyond me. http://ideone.com/Xvp5U is where I gave up.

There is a quite easy solution using boost::lambda with its comma operator. In my case I am using it for a modificator function which is defined as (B is an arbitrary class for e.g. and A is a class which should be altered but resides in B and should not go outside)
void B::modify( boost::function<void(A&)> func );
My intention is to pass only the modificator to the modify function which makes it more easy to gain control when it is modified (for e.g. for emitting signals).
Sometimes I want to apply 2 modifier:
void A::setInvalid();
void A::setX( int x );
Calling in 2 steps which is not the way (just as reference to show how we want to use the modify method):
instanceA->modify(
boost::bind( &A::setInvalid, _1 );
instanceA->modify(
boost::bind( &A::setX, _1, 4 );
Using boost::lambda this can be joined to a single function call and therefore only one function is created:
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
using namespace boost::lambda;
instanceA->modify(
( bind(&A::setInvalid, boost::lambda::_1)
, bind(&A::setX, boost::lambda::_1, 4) ) );
Related to your question this would look then:
using namespace boost::lambda;
boost::function<void()> func = ( bind(f), bind(g) )

Related

Hold a collection of member function pointers and decorated member function pointers

As a part of a much larger project, one of my objects (Thing in MWE) has a set of filters (filterStrong, filterWeak) defined on it. The goal is to use all the implemented filters in complexFilteringProcedure, where the user could chose the filtering rule through a parameter, and the function itself would depend on the success of the filtering rule chosen. The function complexFilteringProcedure would act on an object of type Thing, and call one of its private methods (filtering rules) depending on the parameter.
I implemented this by holding a vector of all possible filters in filteringOptions and implementing a single public filtering interface, filterUsingRule. Ideally, this would allow me to later on add new filtering rules to the project as I need them, and only modify the setFilteringFunction where the filter list is initialized.
Now, I started writing a new set of filtering rules, and realized all of them could be obtained by decorating the current filtering rules all in the same manner (softenFilter; please do correct me if "decorating" is the wrong expression here). I remembered reading into std::bind recently and taught, great. I would also like to add all the decorated filtering rules in my list of filteringOptions, that is, every original filter decorated with softenFilter.
Reading up a little bit more on std::bind, I think the possible reasons for my problems are twofold:
the return type of std::bind is a templated mess, and definitely not Thing::filteringFunction
I might be binding the this referring to the calling object when defining softStrong and softWeak
But, I am stuck further than that, not sure how to look for a solution to my specific problem. My main question are: Can this functionality be achieved? (functionality of filterUsingRule) and further, Can this functionality be achieved elegantly? (I know I could always define a set of functions bool softStrong(int param) { return softenFilter(filterStrong, param); } that manually bind the filters to the decorator, but I was hoping that std::bind or some new C++ magic would help with that).
The MWE recreating what I have successfully done and what I would like to achieve is as follows:
#include <iostream>
#include <vector>
#include <functional>
class Thing{
private:
int basicFilter;
typedef bool (Thing::*filteringFunction)(int);
static std::vector<filteringFunction> filteringOptions;
bool filterStrong(int parameter) {return parameter > basicFilter*2;}
bool filterWeak(int parameter) {return parameter > basicFilter;}
bool softenFilter(filteringFunction f, int parameter){
if (!((this->*(f))(parameter)))
return (this->*(f))(parameter+2);
return true;
}
void setFilteringFunctions(void){
Thing::filteringOptions.emplace_back(&Thing::filterStrong);
Thing::filteringOptions.emplace_back(&Thing::filterWeak);
auto softStrong = std::bind(&Thing::softenFilter,
&Thing::filterStrong,
std::placeholders::_1); // ok
auto softWeak = std::bind(&Thing::softenFilter,
&Thing::filterWeak,
std::placeholders::_1); // ok
filteringOptions.emplace_back(&softStrong); // how?
filteringOptions.emplace_back(softWeak); // how?
}
public:
Thing(int basicFilter) : basicFilter(basicFilter){
if (Thing::filteringOptions.empty())
setFilteringFunctions();
}
bool filterUsingRule(int parameter, int rule = 0){
return ((int)Thing::filteringOptions.size() > rule) &&
(this->*(Thing::filteringOptions[rule]))(parameter);
}
};
std::vector <Thing::filteringFunction> Thing::filteringOptions(0);
void complexFilteringProcedure(Thing &aThing, int parameter, int rule){
// do a lot of things
if (aThing.filterUsingRule(parameter, rule))
std::cout << "Filtering with " << rule << "successful" << std::endl;
else
std::cout << "Filtering with " << rule << "failed" << std::endl;
// and some more things
}
int main(void){
Thing myThing(5), otherThing(10);
complexFilteringProcedure(myThing, 7, 0); // uses strong rule
complexFilteringProcedure(otherThing, 7, 1); // uses weak rule
complexFilteringProcedure(myThing, 7, 2); // how to do this correctly?
complexFilteringProcedure(otherThing, 7, 3); // or this?
}
You might use std::function
using filteringFunction = std::function<bool (Thing&, int)>;
and then
void setFilteringFunctions()
{
Thing::filteringOptions.emplace_back(&Thing::filterStrong);
Thing::filteringOptions.emplace_back(&Thing::filterWeak);
auto softStrong = std::bind(&Thing::softenFilter,
std::placeholders::_1,
&Thing::filterStrong,
std::placeholders::_2
);
auto softWeak = std::bind(&Thing::softenFilter,
std::placeholders::_1,
&Thing::filterWeak,
std::placeholders::_2);
Thing::filteringOptions.emplace_back(&softStrong);
Thing::filteringOptions.emplace_back(&softWeak);
// or
Thing::filteringOptions.emplace_back([](Thing& instance, int param){
return instance.filterStrong(param + 2) });
}
You'll have to use a specialization of std::function as your vector element type. The key issue is that the object returned by std::bind() is not a bare function pointer. It is rather a Callable -- a function object -- it is some type (exactly what type is unimportant and in fact unspecified) that has an operator() with the appropriate return type which takes the appropriate parameters. This is exactly the role of std::function -- a type which can wrap any Callable of the correct signature in a way that lets you handle it with a known concrete type regardless of the actual type of the Callable.
typedef std::function<bool(int)> filteringFunction;
static std::vector<filteringFunction> filteringOptions;
// now can you store your member function pointers in
// filteringOptions after bind()ing the first parameter
// as you've already done
To satisfy the skeptics, here is the OP's code modified to use this technique.
#include <iostream>
#include <vector>
#include <functional>
class Thing{
private:
int basicFilter;
typedef std::function<bool(int)> filteringFunction;
static std::vector<filteringFunction> filteringOptions;
bool filterStrong(int parameter) {return parameter > basicFilter*2;}
bool filterWeak(int parameter) {return parameter > basicFilter;}
bool softenFilter(filteringFunction f, int parameter){
if (!f(parameter))
return f(parameter + 2);
return true;
}
void setFilteringFunctions(void){
filteringFunction strong = std::bind(&Thing::filterStrong,
this, std::placeholders::_1);
filteringFunction weak = std::bind(&Thing::filterWeak,
this, std::placeholders::_1);
filteringFunction softStrong = std::bind(&Thing::softenFilter,
this, strong, std::placeholders::_1);
filteringFunction softWeak = std::bind(&Thing::softenFilter,
this, weak, std::placeholders::_1);
filteringOptions.emplace_back(softStrong);
filteringOptions.emplace_back(softWeak);
}
public:
Thing(int basicFilter) : basicFilter(basicFilter){
if (Thing::filteringOptions.empty())
setFilteringFunctions();
}
bool filterUsingRule(int parameter, int rule = 0){
return ((int)Thing::filteringOptions.size() > rule) &&
filteringOptions[rule](parameter);
}
};
std::vector <Thing::filteringFunction> Thing::filteringOptions(0);
void complexFilteringProcedure(Thing &aThing, int parameter, int rule){
// do a lot of things
std::cout << "Filtering: " << aThing.filterUsingRule(parameter, rule) << std::endl;
// and some more things
}
int main(void){
Thing myThing(5), otherThing(10);
complexFilteringProcedure(myThing, 7, 0); // uses strong rule
complexFilteringProcedure(otherThing, 7, 1); // uses weak rule
//complexFilteringProcedure(myThing, 7, 2); // how to use soft strong rule?
//complexFilteringProcedure(otherThing, 7, 3); // how to use soft weak rule?
}
typedef std::function<bool(Thing*, int)> filteringFuction;
Now you can use static functions as well as std::bind and lambda or any callable that accepts an int and returns bool.
static bool test(Thing*, int);
static bool decoratee(Thing*, bool , int);
this->filteringOptions.emplace_back([](Thing* sth, int x){return false;});
this->filteringOptions.emplace_back(&Thing::weakFilter);
this->filteringOptions.emplace_back(std::bind(decoratee, _1, false, _2));
this->filteringOptions.emplace_back(&test);
int param;
for(auto& callee:this->filteringOptions)
callee(this,param);

Using this keyword to access function pointers in C++

Shown below is a working code. But I want to use "this" keyword to call my function pointers inside my implementation (e.g inside the constructor implementation). Please help me to come up with a solution.
My system is
g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-55)
Working Code
#include <iostream>
#include <string>
#include <map>
using namespace std;
class TestClass{
public:
typedef int (TestClass::*FunctionPtr)(int);
map <string, FunctionPtr> mFnPtrMap;
int Function1( int nAdd ) { return nAdd + 1; }
int Function2( int nAdd ) { return nAdd + 2; }
TestClass() {
mFnPtrMap.insert( make_pair( "Function1", &TestClass::Function1) );
mFnPtrMap.insert( make_pair( "Function2", &TestClass::Function2) );
}
int CallFunction( const string & s, int n ) {
FunctionPtr fp = mFnPtrMap[s];
return (this->*fp)(n);
}
};
int main() {
TestClass ts;
cout << ts.CallFunction( "Function1", 0 ) << endl;
cout << ts.CallFunction( "Function2", 0 ) << endl;
}
What I want to do is:
My expectation is to change it into something like this (use 'this->' instead of 'TestClass::')
mFnPtrMap.insert( make_pair( "Function1", &this->Function1) );
It gives me a compiler error. It even suggests me to use TestClass:: name resolution.
"ISO C++ forbids taking the address of a bound member function to form
a pointer to member function. Say &TestClass::Function1"
Does that mean it's not possible? If someone could give me an explanation also, it would help me to understand the theory underneath. Thank you.
If I had to guess for a reason behind this part of the C++ standard, it's that the types of expressions are hardly equivalent. Just compare how you would need to call the function if in a single expression without the function call as some sort of indirection:
(this->*TestClass::function)(); // Binding the member pointer to an instance
Here we bind the member pointer to an instance with the ->* operator which fills the implicit T* argument each member function has, the one named this. Some other language ask you to provide it explicitely, for example Python but I'm sidetracking a bit.
this->function();
Here the subexpression this->function already bound the parameter of this to the local this object which mean that this does in fact in no way refer to a function. Consequently, you can not take an address of it.
You could argue that this should be allowed as part of the standard but consider the fact that you can shadow function declarations in child classes. That means that introducing a second expression for expressing &TestClass::function would only introduce confusion. In the current form it is very clear which function we are referring to whereas in a this->function form it would not be, especially newcomers might assume that this is completely dynamic as this is not a static object. It would also not be interely unreasonable to assume that there in fact is a difference between the expressions.
In the mean time, I can only offer a way to remove the explicit referal to the class by some type level computations:
#include <type_traits>
template<typename T>
using This = typename std::remove_const<typename std::remove_pointer<T>::type>::type;
TestClass::TestClass() {
mFnPtrMap.insert( make_pair( "Function1", &This<decltype(this)>::Function1) );
mFnPtrMap.insert( make_pair( "Function2", &This<decltype(this)>::Function2) );
}

How to get the arguments binded into boost::function?

From the boost::bind docs( http://www.boost.org/doc/libs/1_53_0/libs/bind/bind.html#with_functions ), "The arguments that bind takes are copied and held internally by the returned function object", but if there's a way I could get the arguments copied in those function object?
i.e.:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <string>
using namespace std;
void doSomthing(std::string str)
{
}
int main()
{
boost::function<void(void)> func_obj = boost::bind(&doSomthing, "some string");
//how can I get the std::string argument("some string") through func_obj?
}
thanks in advance.
There's not really much you can do with a Boost.Function object, except call it - and that's by design. (You can copy it, destroy it, compare to NULL, but not much more).
Consider the following code:
void Foo () {}
void Bar ( int i ) { printf ( "%d", i ); }
boost::function<void(void)> fFoo (Foo);
boost::function<void(void)> fBar = boost::bind (Bar, 23);
These two objects are designed to be treated identically. They are the same type, and behave the same. There's no mechanism in boost function for distinguishing between them.
For a great description of the techniques used in Boost.Function (and other places), check out Nevin Liber's type erasure talk from Boostcon 2010

What is wrong with my Phoenix lambda expression?

I would expect the following example Boost Phoenix expression to compile.
What am I missing?
int plus(int a,int b)
{
return a+b;
}
void main(int argc,char** argc)
{
auto plus_1 = phx::bind(&plus,1,arg1);
auto value = phx::lambda[phx::val(plus_1)(arg1)]()(1);
std::cout << value << std::endl;
}
auto plus_1 = phx::bind(&plus,1,arg1);
After this line, plus_1 is a function object that takes one int argument and adds one to it.
phx::lambda[plus_1(arg1)](1);
Whoops. This isn't going to work because (as we said above) plus_1 is a function object that takes one int argument and adds one to it. Here, you're trying to invoke it with arg1.
It isn't obvious from your code what you expect it to do. Can you clarify?
====EDIT====
I see you've edited the code in your question. Your code is still wrong but for a different reason now. This:
phx::val(plus_1)(arg1)
... uses val to create a nullary function that returns the plus_1 unary function. You then try to invoke the nullary function with arg1. Boom.
Here is code that executes and does (what I believe) you intend:
#include <iostream>
#include <boost/phoenix/phoenix.hpp>
namespace phx = boost::phoenix;
using phx::arg_names::arg1;
int plus(int a,int b)
{
return a+b;
}
int main()
{
auto plus_1 = phx::bind(&plus, 1, arg1);
int value = phx::bind(phx::lambda[plus_1], arg1)(1);
std::cout << value << std::endl;
}
The first bind takes the binary plus and turns it into a unary function with the first argument bound to 1. The second bind creates a new unary function that is equivalent to the first, but it does so by safely wrapping the first function using lambda. Why is that necessary? Consider the code below, which is equivalent, but without the lambda:
// Oops, wrong:
int value = phx::bind(phx::bind(&plus, 1, arg1), arg1)(1);
Notice that arg1 appears twice. All expressions get evaluated from the inside out. First, we'll bind the inner arg1 to 1, then evaluate the inner bind yielding 2, which we then try to bind and invoke. That's not going to work because 2 isn't callable.
The use of lambda creates a scope for the inner arg1 so it isn't eagerly substituted. But like I said, the use of the second bind, which forces the need for lambda, yields a function that is equivalent to the first. So it's needlessly complicated. But maybe it helped you understand about bind, lambda and Phoenix scopes.
It's not clear to me what you're trying to accomplish by using lambda here, but if you just want to call plus_1 with 1 (resulting in 2), it's much simpler than your attempt:
#include <iostream>
#include <boost/phoenix.hpp>
int plus(int a, int b)
{
return a + b;
}
int main()
{
namespace phx = boost::phoenix;
auto plus_1 = phx::bind(plus, 1, phx::arg_names::arg1);
std::cout << plus_1(1) << '\n';
}
Online demo
If this isn't what you're trying to accomplish, then you need to describe what you actually want. :-]
Perhaps this can explain it better.
Phoenix is not magic; it is first and foremost C++. It therefore follows the rules of C++.
phx::bind is a function that returns a function object, an object which has an overloaded operator() that calls the function that was bound. Your first statement stores this object into plus_1.
Given all of this, anytime you have the expression plus_1(...), this is a function call. That's what it is; you are saying that you want to call the overloaded operator() function on the type of that object, and that you are going to pass some values to that function.
It doesn't matter whether that expression is in the middle of a [] or not. phx::lambda cannot make C++ change its rules. It can't make plus_1(...) anything other than an immediate function call. Nor can arg1 make plus_1(...) not an immediate function call.

generic non-invasive cache wrapper

I'm trying create a class which adds functionality to a generic class, without directly interfacing with the wrapped class. A good example of this would be a smart pointer. Specifically, I'd like to create a wrapper which caches all the i/o for one (or any?) method invoked through the wrapper. Ideally, the cache wrapper have the following properties:
it would not require the wrapping class to be changed in any way (i.e. generic)
it would not require the wrapped class to be changed in any way (i.e. generic)
it would not change the interface or syntax for using the object significantly
For example, it would be really nice to use it like this:
CacheWrapper<NumberCruncher> crunchy;
...
// do some long and ugly calculation, caching method input/output
result = crunchy->calculate(input);
...
// no calculation, use cached result
result = crunchy->calculate(input);
although something goofy like this would be ok:
result = crunchy.dispatch (&NumberCruncher::calculate, input);
I feel like this should be possible in C++, although possibly with some syntactic gymnastics somewhere along the line.
Any ideas?
I think I have the answer you are seeking, or, at least, I almost do. It uses the dispatch style you suggested was goofy, but I think it meets the first two criteria you set forth, and more or less meets the third.
The wrapping class does not have to be modified at all.
It doesn't modify the wrapped class at all.
It only changes the syntax by introducing a dispatch function.
The basic idea is to create a template class, whose parameter is the class of the object to be wrapped, with a template dispatch method, whose parameters are the argument and return types of a member function. The dispatch method looks up the passed in member function pointer to see if it has been called before. If so, it retrieves the record of previous method arguments and calculated results to return the previously calculated value for the argument given to dispatch, or to calculate it if it is new.
Since what this wrapping class does is also called memoization, I've elected to call the template Memo because that is shorter to type than CacheWrapper and I'm starting to prefer shorter names in my old age.
#include <algorithm>
#include <map>
#include <utility>
#include <vector>
// An anonymous namespace to hold a search predicate definition. Users of
// Memo don't need to know this implementation detail, so I keep it
// anonymous. I use a predicate to search a vector of pairs instead of a
// simple map because a map requires that operator< be defined for its key
// type, and operator< isn't defined for member function pointers, but
// operator== is.
namespace {
template <typename Type1, typename Type2>
class FirstEq {
FirstType value;
public:
typedef std::pair<Type1, Type2> ArgType;
FirstEq(Type1 t) : value(t) {}
bool operator()(const ArgType& rhs) const {
return value == rhs.first;
}
};
};
template <typename T>
class Memo {
// Typedef for a member function of T. The C++ standard allows casting a
// member function of a class with one signature to a type of another
// member function of the class with a possibly different signature. You
// aren't guaranteed to be able to call the member function after
// casting, but you can use the pointer for comparisons, which is all we
// need to do.
typedef void (T::*TMemFun)(void);
typedef std::vector< std::pair<TMemFun, void*> > FuncRecords;
T memoized;
FuncRecords funcCalls;
public:
Memo(T t) : memoized(t) {}
template <typename ReturnType, typename ArgType>
ReturnType dispatch(ReturnType (T::* memFun)(ArgType), ArgType arg) {
typedef std::map<ArgType, ReturnType> Record;
// Look up memFun in the record of previously invoked member
// functions. If this is the first invocation, create a new record.
typename FuncRecords::iterator recIter =
find_if(funcCalls.begin(),
funcCalls.end(),
FirstEq<TMemFun, void*>(
reinterpret_cast<TMemFun>(memFun)));
if (recIter == funcCalls.end()) {
funcCalls.push_back(
std::make_pair(reinterpret_cast<TMemFun>(memFun),
static_cast<void*>(new Record)));
recIter = --funcCalls.end();
}
// Get the record of previous arguments and return values.
// Find the previously calculated value, or calculate it if
// necessary.
Record* rec = static_cast<Record*>(
recIter->second);
typename Record::iterator callIter = rec->lower_bound(arg);
if (callIter == rec->end() || callIter->first != arg) {
callIter = rec->insert(callIter,
std::make_pair(arg,
(memoized.*memFun)(arg)));
}
return callIter->second;
}
};
Here is a simple test showing its use:
#include <iostream>
#include <sstream>
#include "Memo.h"
using namespace std;
struct C {
int three(int x) {
cout << "Called three(" << x << ")" << endl;
return 3;
}
double square(float x) {
cout << "Called square(" << x << ")" << endl;
return x * x;
}
};
int main(void) {
C c;
Memo<C> m(c);
cout << m.dispatch(&C::three, 1) << endl;
cout << m.dispatch(&C::three, 2) << endl;
cout << m.dispatch(&C::three, 1) << endl;
cout << m.dispatch(&C::three, 2) << endl;
cout << m.dispatch(&C::square, 2.3f) << endl;
cout << m.dispatch(&C::square, 2.3f) << endl;
return 0;
}
Which produces the following output on my system (MacOS 10.4.11 using g++ 4.0.1):
Called three(1)
3
Called three(2)
3
3
3
Called square(2.3)
5.29
5.29
NOTES
This only works for methods which take 1 argument and return a result. It doesn't work for methods which take 0 arguments, or 2, or 3, or more arguments. This shouldn't be a big problem, though. You can implement overloaded versions of dispatch which take different numbers of arguments up to some reasonable max. This is what the Boost Tuple library does. They implement tuples of up to 10 elements and assume most programmers don't need more than that.
The possibility of implementing multiple overloads for dispatch is why I used the FirstEq predicate template with the find_if algorithm instead of a simple for loop search. It is a little more code for a single use, but if you are going to do a similar search multiple times, it ends up being less code overall and less chance to get one of the loops subtlely wrong.
It doesn't work for methods returning nothing, i.e. void, but if the method doesn't return anything, then you don't need to cache the result!
It doesn't work for template member functions of the wrapped class because you need to pass an actual member function pointer to dispatch, and an un-instantiated template function doesn't have a pointer (yet). There may be a way around this, but I haven't tried much yet.
I haven't done much testing of this yet, so it may have some subtle (or not-so-subtle) problems.
I don't think a completely seamless solution which satisfies all your requirements with no change in syntax at all is possible in C++. (though I'd love to be proven wrong!) Hopefully this is close enough.
When I researched this answer, I got a lot of help from this very extensive write up on implementing member function delegates in C++. Anyone who wants to learn way more than they realized was possible to know about member function pointers should give that article a good read.
I don't think this can be easily done using just a wrapper as you'll have to intercept the IO calls, so wrapping a class would put the code at the wrong layer. In essence, you want to substitute the IO code underneath the object, but you're trying to do it from the top layer. If you're thinking of the code as an onion, you're trying to modify the outer skin in order to affect something two or three layers in; IMHO that suggests the design might need a rethink.
If the class that you're trying to wrap/modify this way does allow you to pass in the stream (or whatever IO mechanism you use), then substituting that one for a caching one would be the right thing to do; in essence that would be what you'd be trying to achieve with your wrapper as well.
It looks like a simple task, assuming the "NumberCruncher" has a known interface, let's say int operator(int).
Note that you'll need to make it more complicated to support other interfaces. In order to do so, i'm adding another template parameter, an Adaptor. Adaptor should convert some interface to a known interface. Here's simple and dumb implementation with static method, which is one way to do it. Also look what Functor is.
struct Adaptor1 {
static int invoke(Cached1 & c, int input) {
return(c.foo1(input));
}
};
struct Adaptor2 {
static int invoke(Cached2 & c, int input) {
return(c.foo2(input));
}
};
template class CacheWrapper<typename T, typeneame Adaptor>
{
private:
T m_cachedObj;
std::map<int, int> m_cache;
public:
// add c'tor here
int calculate(int input) {
std::map<int, int>::const_iterator it = m_cache.find(input);
if (it != m_cache.end()) {
return(it->second);
}
int res = Adaptor::invoke(m_cachedObj, input);
m_cache[input] = res;
return(res);
}
};
I think what you need is something like a proxy / decorator (design patterns). You can use templates if you don't need the dynamic part of those patterns. The point is that you need to well define the interface that you will need.
I haven't figured out the case for handling object methods, but I think I've got a good fix for regular functions
template <typename input_t, typename output_t>
class CacheWrapper
{
public:
CacheWrapper (boost::function<output_t (input_t)> f)
: _func(f)
{}
output_t operator() (const input_t& in)
{
if (in != input_)
{
input_ = in;
output_ = _func(in);
}
return output_;
}
private:
boost::function<output_t (input_t)> _func;
input_t input_;
output_t output_;
};
Which would be used as follows:
#include <iostream>
#include "CacheWrapper.h"
double squareit(double x)
{
std::cout << "computing" << std::endl;
return x*x;
}
int main (int argc, char** argv)
{
CacheWrapper<double,double> cached_squareit(squareit);
for (int i=0; i<10; i++)
{
std::cout << cached_squareit (10) << std::endl;
}
}
Any tips on how to get this to work for objects?