vendredi 15 mai 2015

Convert from pointer-to-member template function to functional type objects

I have this code that works already:

// mem_fun example
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <map>
using namespace std;

struct C
{
    C(int i): y_(i) {};
    int y_;
    string op1(int x)
    {
       std::ostringstream oss;
       oss << "operation 1: " << x+y_;
       return oss.str();
    }
    string op2(string x)
    {
       std::ostringstream oss;
       oss << "operation 2: " << x << "+" << y_;
       return oss.str();
    }
};

struct container: map<string, C> 
{
// doesn't compile
// void safeOperation(string key, ??? bound_function_and_arg_object )

    template< typename argType >
    void safeOperation(string key, string (C::*mf)(argType a), argType a)
    {
        iterator it = find(key);
        if (it != end())
        {
            C* pC = &(it->second);

            cout << (pC->*mf)(a) << "\n";
        }
        else
        {
            cout << "key: " << key << " missing\n";
        }
    }
};


int main () {
    container objects;

    objects.insert(container::value_type("a1", C(1)));
    objects.insert(container::value_type("b2", C(2)));
    objects.insert(container::value_type("c3", C(3)));

    objects.safeOperation("a1", &C::op1, 1);    
    objects.safeOperation("b2", &C::op1, 2);    
    objects.safeOperation("d4", &C::op1, 4);    
    objects.safeOperation("c3", &C::op2, string("3"));    

  return 0;
}

I'd like to change the template function on the map to use std::mem_fun and to bind the parameters together with the operation, rather than specify them as separate parameters to safeOperation.

In other words, I'd prefer to call safeOperation similar to this:

// wrong, but hopefully communicates what I'm trying to do:
objects.safeOperation(someKey, bind(&C::op1, 4)); 

The sample code is here: http://cpp.sh/74pgb

I'm probably missing something simple, but appreciate the help.

Aucun commentaire:

Enregistrer un commentaire