I was having trouble with this, and I couldn't find a solution on SO. It took me a while to figure it out so I thought I'd post it, in case its useful for someone else
Problem:
I have a set of functors of different types, which I want to store in a std::map and then call later sort of like a switch statement/factory.
class Foo {
public:
void operator() (int x) {
std::cout << "In foo" << x << std::endl;
}
};
class Bar {
public:
void operator() (int x) {
std::cout << "In Bar" << x << std::endl;
}
};
The map looks like
std::map<int,boost::function<void(int)>> maps;
And the inserts look like
maps.insert(std::make_pair(1,boost::bind(&Foo::operator(),Foo(),_1)));
And you can call it like
auto iter = maps.find(1);
iter->second(123);
Looking at the solution it's quite simple one liner, compared to the mental gymnastics trying to figure it out - oh well :)
What i was trying to do originally was to store boost::signals2::signal objects so I could chain a set of factories,in the map, but I never did figure that out. So for a question, how would I store those instead in a map?
std::map<std::string,boost::signals2::signal<void(int)>> m_factory;
// Create the object I want to store
boost::signals2::signal<void(int)> sig;
sig.connect(Foo());
// This fails
m_factory.insert(std::make_pair("Blah",sig));
but I get
std::pair<_Ty1,_Ty2> std::_Tree<_Traits>::insert(std::pair<const _Kty,_Ty> &&)' : cannot convert parameter 1 from 'std::pair<_Ty1,_Ty2>' to 'std::pair<_Ty1,_Ty2> &&
Edit Simplified the example further
Edit 2 - fix bug where I declared map with reference
Further to this, this seems to work fine
typedef boost::signals2::signal<void(int)> Signal;
m_factory["Blah"] = Signal().connect(Foo());
which I thought was logically the same as make_pair?
boost::signals are non-copyable, which makes them not suitable to be used with std containers. You should use pointers (possibly smart pointers) to the signal as in
typedef boost::signals2::signal<void(int)> sig;
typedef std::shared_ptr<sig> pSig;
typedef std::map<int, pSig> map_sig;
void f(int){}
int main(){
pSig s(new sig);
s->connect(f);
map_sig m;
m.insert( map_sig::value_type(1, s) );
}
(you can try the code here).
Related
I have three structs (Foo, Bar, Fruit) and I want a vector to hold each struct like vector<Foo> Foo_holder; vector<Bar> Bar_holder; vector<Fruit> Fruit holder; and then I want to try and put all three of those vectors into one vector. So it should end up like this with Vector_holder being the top level vector that I wish to know how to create:
Vector_holder
--- Foo_Holder
------Instance of Foo
--- Bar_holder
------Instance of Bar
--- Fruit_holder
------Instance of Fruit
How do I go about doing this?
The possible duplicate question lists a problem that the vectors must be the same size or the code breaks, and the vectors in my question will be shifting size a whole lot. I also feel this would help beginner C++ learners more than the other question.
The solution I found here works for me and is overall alot simpler than the nearly essay long answer. I'm more of a beginner in C++ and as such appreciate the easier to understand answer here.
Whenever such a grouping makes sense, I tend to put it into a struct and hence name it. In this case,
struct FooBarFruitHolder {
std::vector<Foo> foos;
std::vector<Bar> bars;
std::vector<Fruit> fruits;
};
which you can then use as
std::vector<FooBarFruitHolder> vec;
vec.emplace_back();
and e.g. fill it with objects:
/* Add a Foo element to all FooBarFruitHolder instances. */
for (auto&& fooBarFruitHolder : vec)
fooBarFruitHolder.foos.emplace_back(/* Arguments passed to Foo ctor */);
The naming is essential here, so choose what fits best in your application. Initialization might also be easier to read when you pass parts of this nested datastructure into functions which setup the member variables, e.g.
void initialize(std::vector<Foo>& foos)
{
foos.emplace_back(/* Arguments for first Foo object */);
foos.emplace_back(/* Arguments for second Foo object */);
}
initialize(vec.front().foos);
vector to hold each struct like vector Foo_holder; vector
Bar_holder; vector Fruit holder; and then I want to try and put
all three of those vectors into one vector.
One way to interpret your (somewhat ambiguous) statement is that you also want a single vector that holds all N element types in it. (But I suspect you will like lubgr's answer better.)
For this the third vector, I suggest you consider Polymorphism.
If you derive each of your structs from an interface class, perhaps
class FooBarFruit_t
{
//...
virtual void whistle() = 0;
virtual void bounce() = 0;
virtual void f1() = 0;
virtual void f2() = 0;
virtual void f3() = 0;
virtual void reflect();
//...
}
then you can easily create a vector where any of the N types can be loaded
std::vector<FooBarFruit_t*> holder;
The next challenge will be to create virtual methods that each derived class can support.
a) They may be abstract, f1(), f2() ...
b) They may be very specific, such as whistle(), which is something that only foo can do (and bars and fruit would take no action on being commanded to whistle()).
[I'm not sure what kind of behavior these typically in-animate instances might take, but software is where abstraction really helps.]
What this buys you is, at run time, you do not have to know what kind of FooBarFruit_t you are commanding to action.
By invoking f3(), each instance (foo or bar or fruit) will do what what you ask, and each f3() simply fulfills the expectation you have for that type.
If the instance does not reflect(), you can either implement a method that a) does nothing, or b) invokes FooBarFruit_t::reflect(). Or several other options.
Consider that you might want to display all objects:
for (auto fbf : holder) fbf->show();
for (auto fbf : holder) fbf->diagnostic(); // or diagnostic
for (auto fbf : holder) fbf->reset(); // or reset
Any reason these need to be considered different?
There should not be a place where you feel the need to do something specific based on type:
void something() {
for (auto fbf : holder) {
switch(fbf.type())
{ // vvvvv - enumeration of types
case Foo: foosomething(); break;
case Fruit: fruitsomething(); break;
case Bar: barsomething(); break;
default : assert(0); break;
}
}
}
But no one will stop you from doing so you think you must.
You could use Boost's zip iterator to "zip together" the different vectors:
vector<Foo> Foo_holder;
vector<Bar> Bar_holder;
vector<Fruit> Fruit holder;
/* ... insert elements etc. */
auto start = boost::make_zip_iterator(
std::make_tuple(ia.begin(), d.begin(), ib.begin())
);
auto end = boost::make_zip_iterator(
std::make_tuple(ia.end(), d.end(), ib.end())
);
Now, this doesn't result in a vector, just a pair of iterators. But now you can use them with STL algoritms. For example:
std::for_each(start, end, [](auto a_foo, auto a_bar, auto a_fruit) {
std::cout << "The Foo element is " << foo << "\n";
std::cout << "The Bar element is " << bar << "\n";
std::cout << "The Fruit element is " << fruit << "\n";
}
and you can also use these iterators to create a single range object. This is described, for example, in this answer by #leemes to a related question of mine.
I want to implement my own "simple" container which will have map properties but also keeps insertion order. I've heard about boost::multi_index but I find it very difficult to understand for what I want.
So I made a templated class:
template<typename KEY, typename VALUE>
class MyMap {
private :
std::vector<KEY> m_keys;
std::vector<VALUE> m_values;
public :
void insert(KEY& key, VALUE& val) {
//Test if key exists //
m_keys.push_back(key);
m_values.push_back(val);
}
/* Other methods like erase/size/operator[]/begin/etc. */
};
Just to test it, I wanted to do something like this:
int main() {
MyMap<string,int> m;
m.insert("test",1);
m.insert("cat",2);
for(auto& item : m) {
cout << item << endl;
cout << m[item] << endl;
}
}
But I keep getting a compilation error on inserts (and [ ]) as it translates my KEY into a basic_string and not a string. It's driving me crazy and I can't find any answer (or any word to properly describe my problem to research for an answer). I guess it has something to do with allocators but I can't manage to understand how to fix it.
How can I make my map do this conversion but also stays general as I will need it with other (own-implemented) classes?
EDIT : After solving "string" problem, I had problems when passing int because it was waiting for an &int. Followed kebs advice and implemented a vector> instead and got rid of conversion problems... :)
You can't build a reference from a const char* (even though it gets casted to a string), try this instead:
template<typename KEY, typename VALUE>
void insert(KEY key, VALUE val) {
m_keys.push_back(key);
m_values.push_back(val);
}
More precisely, the compiler is pretty clear about the problem:
error: invalid initialization of non-const reference of type 'std::basic_string&' from an rvalue of type 'std::basic_string'
m.insert("test",1);
I want to make a class that will have a single get template method which will receive an std::string to find in a std::map the right variable and return it.
The std::map should store any type of variable, so I used boost::any, so far the std::map looks like that:
std::map<std::string, boost::any> variables_;
for the get function, I tried something like that:
template <typename T>
T get(std::string& parameter)
{
return variables_[parameter];
}
But no lucky, my question is, is that even possible to do? If so, how?
The basic idea is that I dont want to make an specific method to every specific variable in my class, so other classes dont need to know about every get method of it.
Thanks!
ps: For anyone asking why I want this, here is a resume of it, I have a lot of algorithms, that will run in a certain order, and it will use that for the last one already runned algorithm. So, what I want is to make an xml file, that will tell what algorithms will run, in which order and what data it will use from another algorithm.
So, for example, algorithm A have an variable named "threshold", algorithm B need that information, so, normally it will have to ask it from the A using something like A.getThreshold, but as far as I know, I can't call a object function with it name in an string (from the xml file), so my solution would be have only an get function which i pass the variable name I want and that function will return it to me.
An alternative solution would be to "wrap" the boost::any object into another object which can be automatically converted to anything you want. I don't think it's a good practice but it's the best fit according to your question.
class AnyWrapper {
boost::any value;
public:
AnyWrapper(const boost::any& val) : value(val) {}
template<typename T> operator T() {
return boost::any_cast<T>(value);
}
}
And your getter would be something like :
AnyWrapper get(std::string& parameter)
{
return variables_[parameter]; // variables is a std::map<std::string, boost::any>
}
And then you should be able to retrieve your elements like that :
int integerValue = myContainer.get("age");
std::string stringValue = myContainer.get("name");
But again, this is not a clean solution. There is a reason why the boost authors chose to make the any_cast explicit :)
An boost::any value won't implicitly convert to a type T, you have to request that cast manually:
template <typename T>
T get(std::string& parameter)
{
return boost::any_cast<T>(variables_[parameter]);
}
The call will fail with a boost::bad_any_cast exception if the type stored in the any is not exactly T.
You can also return an boost::any. You lose encapsulation of your implementation, but depending on how you use the return value, it may be the better way.
What you want is not possible as you are trying to mix compile time (template) and runtime (map lookup) code.
You either have to make it fully runtime:
struct base_type { virtual ~base_type{} };
struct derived_type: base_type { ... };
std::map<std::string, base_type*> lookup_map;
base_type* get(std::string const& key) { return lookup_map[key]; }
Or fully compile time (boost.fusion example):
#include <boost/fusion/container/map.hpp>
#include <boost/fusion/sequence/intrinsic/at_key.hpp>
#include <boost/fusion/sequence/intrinsic/value_at_key.hpp>
namespace bf=boost::fusion;
struct key_a; // analogues of string keys in compile time world
struct key_b;
struct key_c;
typedef bf::map<
bf::pair<key_a, long>,
bf::pair<key_b, double>,
bf::pair<key_c, char const*>
> rtmap_t;
rtmap_t rtmap;
template <class Key>
void set_value(typename bf::result_of::value_at_key<rtmap_t, Key>::type const& val)
{
bf::at_key<Key>(rtmap) = val;
}
template <class Key>
typename bf::result_of::at_key<rtmap_t, Key>::type get_value()
{
return bf::at_key<Key>(rtmap);
}
#include <iostream>
int main()
{
char const* cval = "hello metaprogramming";
set_value<key_a>(123l);
set_value<key_b>(456.789);
set_value<key_c>(cval);
std::cout << get_value<key_a>() << std::endl;
std::cout << get_value<key_b>() << std::endl;
std::cout << get_value<key_c>() << std::endl;
return 0;
}
Considering the information you provided in your question I would choose runtime variant with dynamic polymorphism.
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?
I'm working on a fairly complex project, a custom encryption routine if you will (just for fun) and I've run into this issue in designing my code layout.
I have a number of functions that I want to be able to call by index. Specifically, I need to be able to call one randomly for the encrypt process, but then address that by a specific index in the decrypt process.
I was considering a classic function array, but my main concern is that a function array would be tricky to maintain, and a little ugly. (The goal is to get each function pair in a separate file, to reduce compile times and make the code easier to manage.) Does anyone have a more elegant C++ solution as an alternative to a function array? Speed isn't really an issue, I'm more worried about maintainability.
-Nicholas
What's wrong with function array?
You need to call functions by index. So they must be put into some "indexable by index" structure somehow. Array is probably the simplest structure that suits this need.
Example (typing out of my head, might not compile):
struct FunctionPair {
EncodeFunction encode;
DecodeFunction decode;
};
FunctionPair g_Functions[] = {
{ MyEncode1, MyDecode1 },
{ MySuperEncode, MySuperDecode },
{ MyTurboEncode, MyTurboDecode },
};
What is "ugly" or "hard to maintain" in the approach above?
You could write something like:
class EncryptionFunction
{
public:
virtual Foo Run(Bar input) = 0;
virtual ~MyFunction() {}
};
class SomeSpecificEncryptionFunction : public EncryptionFunction
{
// override the Run function
};
// ...
std::vector<EncryptionFunction*> functions;
// ...
functions[2]->Run(data);
You could use operator() instead of Run as the function name, if you prefer.
An object with an operator() method defined can act a lot like a function but be generally nicer to work with.
Polymorphism could do the trick: you couldf follow the strategy pattern, considering each strategy to implement one of your functions (or a pair of them).
Then create a vector of strategies, and use this one instead of the function list.
But frankly, I don't see the problem with the function array; you can easily create a typedef to ease the readability. Effectifely, you will end up with exactly the same file structure when using the strategy pattern.
// functiontype.h
typedef bool (*forwardfunction)( double*, double* );
// f1.h
#include "functiontype.h"
bool f1( double*, double* );
// f1.c
#include "functiontype.h"
#include "f1.h"
bool f1( double* p1, double* p2 ) { return false; }
// functioncontainer.c
#include "functiontype.h"
#include "f1.h"
#include "f2.h"
#include "f3.h"
forwardfunction my_functions[] = { f1, f2, f3 };
The function declaration and definitions are in separate files - compile time is ok.
The function grouping is in a separate file, having a dependency to the declarations only
You could take a look at the Boost.Signals library. I believe it has the ability to call its registered functions using an index.
Try Loki::Functor class. More info at CodeProject.com
You need to use an array of function pointers. The only catch is that all the functions have to have basically the same prototype, only the name of the function and passed argument names can vary. The return type and argument types (as well as the number of arguments and order) must be identical.
int Proto1( void );
int Proto2( void );
int Proto3( void );
int (*functinPointer[3])( void ) =
{
Proto1,
Proto2,
Proto3
};
Then you can do something like this:
int iFuncIdx = 0;
int iRetCode = functinPointer[iFuncIdx++]();
If you looked in boost::signals library, you'll see an example very nice, that is very elegant:
Suppose you have 4 functions like:
void print_sum(float x, float y)
{
std::cout << "The sum is " << x+y << std::endl;
}
void print_product(float x, float y)
{
std::cout << "The product is " << x*y << std::endl;
}
void print_difference(float x, float y)
{
std::cout << "The difference is " << x-y << std::endl;
}
void print_quotient(float x, float y)
{
std::cout << "The quotient is " << x/y << std::endl;
}
Then if you want to call them in a elegant way try:
boost::signal<void (float, float)> sig;
sig.connect(&print_sum);
sig.connect(&print_product);
sig.connect(&print_difference);
sig.connect(&print_quotient);
sig(5, 3);
And the output is:
The sum is 8
The product is 15
The difference is 2
The quotient is 1.66667