如何存储在一个容器不同的签名功能对象? [英] How to store functional objects with different signatures in a container?

查看:89
本文介绍了如何存储在一个容器不同的签名功能对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,想象一下,我们有2个功能(无效:(无效))(标准::字符串:(INT,标准::字符串) )键,我们可以有10个。所有(或某些)在不同的参数类型采取,并且可以返回不同的类型。我们希望将它们存储在的std ::地图,所以我们得到这样一个API:

  //拥有像一个功能:
INT参考hello world(标准::字符串名称,const int的&安培;号)
{
    名+ =!;
    性病::法院LT&;< 你好,<<命名<<的std :: ENDL;
    返回数;
}
//和
无效i_do_shadowed_stuff()
{
    返回;
}//我们希望能够创造一个地图(或某些类型的类似API),将持有我们的功能对象。像这样:
myMap.insert(性病::对<的std ::字符串,fun_object>(my_method_hello,参考hello world))
myMap.insert(性病::对<的std ::字符串,fun_object>(my_void_method,i_do_shadowed_stuff))
//我们可以在需要使用参数调用的评价:
INT A = MYMAP [my_method_hello(添,25);
MYMAP [my_void_method];

我不知道如何把许多不同的功能在同一容器中。具体来说,使用Boost如何做到这一点的C ++ 03。

该API应该是独立于实际的函数类型(有 int类型的= MYMAP [my_method_hello(添,25); 不是 int类型的= MYMAP< INT,(标准::字符串,INT)>my_method_hello(添,25);


解决方案

 的#include<功能>
#包括LT&;&iostream的GT;
#包括LT&;串GT;
#包括LT&;地图和GT;类API {
    //包含不同的函数指针地图
    无效的typedef(* voidfuncptr)();
    的typedef INT(* stringcrintptr)(标准::字符串,const int的&安培;);    性病::地图<的std ::字符串,voidfuncptr> voida;
    性病::地图<的std ::字符串,stringcrintptr> stringcrint;
上市:
    // API临时类
    //给定的API和一个名称,将其转换为一个函数指针
    //这取决于所使用的参数
    类apitemp {
        常量的std ::字符串n;
        常量API * P;
    上市:
        apitemp(常量标准::字符串&放大器;名,常量API *父)
            :N(名称),P(父){}
        运营商voidfuncptr()
        {返回P-> voida.find(N) - GT;第二位; }
        运营商stringcrintptr()
        {返回P-> stringcrint.find(N) - GT;第二位; }
    };    //新的功能插入到相应的地图
    无效插入(常量标准::字符串&放大器;名称,voidfuncptr PTR)
    {voida [名] = PTR; }
    无效插入(常量标准::字符串&放大器;名称,stringcrintptr PTR)
    {stringcrint [名] = PTR; }
    //运算符[]的名称中途到达正确的功能
    apitemp运算符[](性病::字符串n)常量
    {返回apitemp(N,这一点); }
};

用法:

  API MYMAP;INT参考hello world(标准::字符串名称,const int的&安培;号)
{
    名+ =!;
    性病::法院LT&;< 你好,<<命名<<的std :: ENDL;
    返回数;
}诠释的main()
{
    myMap.insert(my_method_hello,&放大器;参考hello world);
    INT A = MYMAP [my_method_hello(添,25);
}

http://ideone.com/SXAPu 不太pretty。更好的建议是不要做任何事情,甚至远程像whawtever这是你想要做的事。

请注意,这需要以相同的参数的所有功能以返回相同的类型。

So imagine we had 2 functions (void : ( void ) ) and (std::string : (int, std::string)) and we could have 10 more. All (or some of them) take in different argument types and can return different types. We want to store them in a std::map, so we get an API like this:

//Having a functions like:
int hello_world(std::string name, const int & number )
{
    name += "!";
    std::cout << "Hello, " << name << std::endl;
    return number;
}
//and
void i_do_shadowed_stuff()
{
    return;
}

//We want to be capable to create a map (or some type with similar API) that would hold our functional objects. like so:
myMap.insert(std::pair<std::string, fun_object>("my_method_hello", hello_world) )
myMap.insert(std::pair<std::string, fun_object>("my_void_method", i_do_shadowed_stuff) )
//And we could call tham with params if needed:
int a = myMap["my_method_hello"]("Tim", 25);
myMap["my_void_method"];

I wonder how to put many different functions into the same container. Specifically, how to do this in C++03 using Boost.

The API should be independent from the actual function types (having int a = myMap["my_method_hello"]("Tim", 25); not int a = myMap<int, (std::string, int)>["my_method_hello"]("Tim", 25);).

解决方案

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

class api {
    // maps containing the different function pointers
    typedef void(*voidfuncptr)();
    typedef int(*stringcrintptr)(std::string, const int&);

    std::map<std::string, voidfuncptr> voida;
    std::map<std::string, stringcrintptr> stringcrint;
public:
    // api temp class
    // given an api and a name, it converts to a function pointer
    // depending on parameters used
    class apitemp {
        const std::string n;
        const api* p;
    public:
        apitemp(const std::string& name, const api* parent)
            : n(name), p(parent) {}
        operator voidfuncptr()
        { return p->voida.find(n)->second; }
        operator stringcrintptr()
        { return p->stringcrint.find(n)->second; }
    };

    // insertion of new functions into appropriate maps
    void insert(const std::string& name, voidfuncptr ptr)
    { voida[name]=ptr; }
    void insert(const std::string& name, stringcrintptr ptr)
    { stringcrint[name]=ptr; }
    // operator[] for the name gets halfway to the right function
    apitemp operator[](std::string n) const
    { return apitemp(n, this); }
};

Usage:

api myMap; 

int hello_world(std::string name, const int & number )
{
    name += "!";
    std::cout << "Hello, " << name << std::endl;
    return number;
}

int main()
{
    myMap.insert("my_method_hello", &hello_world );
    int a = myMap["my_method_hello"]("Tim", 25);
}

http://ideone.com/SXAPu Not very pretty. Better advice is to not do anything even remotely like whawtever it is you're trying to do.

Note that this requires all functions with the same parameters to return the same type.

这篇关于如何存储在一个容器不同的签名功能对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆