【问题标题】:Storing function pointers in a std::map在 std::map 中存储函数指针
【发布时间】:2015-12-12 02:03:24
【问题描述】:

我正在尝试将函数指针与结构一起存储在映射中。这个想法是当我在结构中找到特定值时执行相应的功能。程序没有编译,当我试图通过 std::make_pair 将数据插入地图时给我很多错误。这是我编写的代码。请指导我在这里做错了什么..

#include "stdafx.h"
#include <iostream>
#include <string>
#include <map>

struct _timeset
{
    int hr1;
    int min1;
    int secs1;
};

_timeset t1 = { 17, 10, 30 };

void fun1(void)
{
    std::cout << "inside fun1\n";
}

void fun2(void)
{
    std::cout << "inside fun2\n";
}

void fun3(void)
{
    std::cout << "inside fun3\n";
}

std::map<_timeset, void(*)()> m1;

int main()
{
    m1.insert(std::make_pair(t1, fun1));  //Compiling errors here



    return 0;
}

我的 STL 基础很差。我正在使用 VS2013 编译器。 另外,在迭代地图时,我可以使用以下内容执行相关功能吗:

std::map<_timeset, void(*)()>::iterator it1;
    int i = 0;
    for (i=0,it1 = m1.begin(); it1 != m1.end(); it1++,i++)
    {

        _timeset _t = it1->first;
         //Check Values in _t, and then execute the corresponding function in the map

            (*it1->second)();
    }

非常感谢,

【问题讨论】:

  • 如果您有编译器错误,您应该将它们包含在问题中。
  • 映射键(在您的情况下为_timeset)应该为它们定义operator&lt;
  • 没有足够的空间容纳所有错误
  • 1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef(193): error C2784: 'bool std::operator &,const std::tuple<_types1...> &)' : 无法从 'const _timeset'推导出 'const std::tuple<_types...> &' 的模板参数>
  • 顺便说一句,typedef 关键字对函数指针非常有用。 typedef 比函数指针语法更易读(而且打字更少)。

标签: c++ c++11 stl


【解决方案1】:

您需要为_timeset 指定比较器才能使std::map 工作,例如:

struct _timeset
{
    int hr1;
    int min1;
    int secs1;
    bool operator<( const _timeset &t ) const {
        return std::make_tuple( hr1, min1, secs1 ) < std::make_tuple( t.hr1, t.min1, t.secs1 );
    }
};

或者您可以按照here 的描述将其设为lamba

在迭代地图时,我可以使用类似的东西执行相关功能

是的,你可以,你也不必复制你的struct _timeset

int i = 0;
for ( it1 = m1.begin(); it1 != m1.end(); it1++,i++)
{

    const _timeset &_t = it1->first;
     //Check Values in _t, and then execute the corresponding function in the map

        (*it1->second)();
}

如果你想存储不同签名的函数,使用std::function:

typedef std::function<void()> func;
std::map<_timeset, func> m1;

void fun1();
void func2( int );
struct foobar { void func3(); };

m1.insert( std::make_pair( t, func1 ) ); // signature matches, no need for bind
m1.insert( std::make_pair( t, std::bind( func2, 123 ) ) ); // signature does not match func2(123) will be called
foobar *pf = ...;
m1.insert( std::make_pair( t, std::bind( func3, pf ) ) ); // signature does not match, pf->func3() will be called
// etc

【讨论】:

  • 一个小问题。如果我想保存具有不同签名的各种功能,我应该如何声明我的地图?例如,我的地图现在包含以下类型的函数:void func(),如果我想存储 int func(int) 或字符串 func(int) 类型的函数等。是否有任何通用解决方案来声明我的地图持有所有函数类型??可能模板是唯一的解决方案。任何例子都会很好。谢谢
  • @XMarshall 使用 std::functionstd::bind,查看更新示例
  • std::function 和 std::bind 在 VS2013 编译器中不可用?
  • 不确定 VS2013,它从 C++11 开始可用,如果你的编译器不支持 C++11,你可以使用 boost 代替。除了 boost 命名空间而不是 stdstd 中占位符的命名空间之外,用法相同
  • std::function 和 std::bind 绝对适用于 VS2013。确保你#include &lt;functional&gt;
猜你喜欢
  • 2011-06-13
  • 2016-05-18
  • 2010-12-27
  • 2011-12-12
  • 2013-06-30
  • 1970-01-01
  • 1970-01-01
  • 2021-06-03
  • 1970-01-01
相关资源
最近更新 更多