【问题标题】:Call map key to invoke function requiring a parameter - how to get working调用映射键来调用需要参数的函数 - 如何开始工作
【发布时间】:2013-05-15 10:31:25
【问题描述】:

这是我的代码。

#include <map>
#include <string>
#include <algorithm>

class maptest {
public:
   int doubler(int val) { return val * 2; }
   int halver(int val) { return val / 2; }
   int negativer(int val) { return val > 0 ? -val : val; }
};


int main() {

   const char* const ID[] = {"doubler", "halver", "negativer" };
   int ID_SIZE = sizeof(ID) / sizeof(*ID);   

   //signature of maths functions
   typedef int (maptest::*mathfunc)(int);


   mathfunc mfuncs[] = { &maptest::doubler, &maptest::halver, &maptest::negativer};

   std::map<std::string, mathfunc> mathmap;   

   for(int i = 0; i < ID_SIZE; ++i) {
       mathmap.insert(std::make_pair(ID[i], mfuncs[i]));
   }

   //C2064: term does not evaluate to a function taking 1 argument
   int result = *mathmap["doubler"](3);

   return 0;
}

我认为如果没有要传递给函数的参数,这将起作用。但是这种方式怎么传参数呢?

【问题讨论】:

    标签: c++ function-pointers


    【解决方案1】:

    您的mathfuncs 是成员函数,因此您需要一个对象来调用它们:

    maptest mt;
    int result = (mt.*(mathmap["doubler"]))(3);
    

    或者,您可以将成员函数设为静态:

    class maptest {
    public:
       static int doubler(int val) { return val * 2; }
       static int halver(int val) { return val / 2; }
       static int negativer(int val) { return val > 0 ? -val : val; }
    };
    

    然后相应地定义mathfunc

    typedef int (*mathfunc)(int);
    

    这将允许您以在原始帖子中调用它们的方式调用它们:

    typedef int (*mathfunc)(int);
    

    请注意,使此设计更加灵活的一种方法是使用std::function,这将允许您使用pass any type of callable object。例如:

    typedef std::function<int(int)> mathfunc;
    
    mathfunc mfuncs[] = {
        &maptest::doubler,
        &maptest::halver,
        &maptest::negativer,
        [] (int i) { return i * 2; } // <== A LAMBDA...
        };
    

    【讨论】:

    • (mt.*(mathmap["doubler"])) 上的括号令人困惑。为什么需要外括号,即这里的括号: (mt.*(mathmap["doubler"])) ?
    • @user619818:没必要,我只是觉得它让事情更清楚了。也许我错了;)
    • 在我的 VS2008 编译器上它是必需的。没关系。
    • @user619818:对不起,我误解了你的问题。需要外括号,而不是内括号。换句话说,这编译:(mt.*mathmap["doubler"])(3);,但这不会:mt.*mathmap["doubler"](3);
    • @user619818:那是因为语法是如何指定的。如果没有括号,编译器会尝试将其解析为 mt.*(mathmap["doubler"](3))
    【解决方案2】:

    您正在调用非静态成员函数。

    执行以下操作。

     maptest  t;
    
     int (maptest::*tptr) (int) =  mathmap["doubler"];
    
     int result =   (t.*tptr)(2);
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-17
      相关资源
      最近更新 更多