【问题标题】:Mapping Strings to Functions with Different Return Types将字符串映射到具有不同返回类型的函数
【发布时间】:2014-10-23 03:30:04
【问题描述】:

我见过这个问题的变体,但它们通常涉及返回相同类型的函数。这是我的代码:

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

using namespace std;

void checkType(int x){
    cout << "we got an int: " << x << endl;
}

void checkType(float x){
   cout << "we got a float: " << x << endl;
}

int getInt(){
   return 1;
}

float getFloat(){
   return -101.23f;
}

int main(){
   map<string, function<float()> > myMap({
      {"int", getInt},
      {"float", getFloat}
   });

   checkType(myMap["int"]());
   checkType(myMap["float"]());

   return 1;
}

这里的目标是根据映射函数返回的内容调用不同版本的重载函数 (checkType)。显然 checkType(float) 函数最终会被调用两次,因为我的地图认为它的所有函数都返回浮点数。

有什么好办法吗?这是一个很好的做法吗?我找到了一个不同的解决方案,但我认为如果这样的事情是合法的,它可能会很性感。

【问题讨论】:

  • 考虑:string s = "int"; checkType(myMap[s]()); 你要这个打电话给checkType(int) 吗?我不明白这是怎么回事。调用哪个重载完全在编译时确定 - 它不可能在运行时根据字符串变量恰好具有的值而改变。
  • 嗯,float 函数不应该被调用两次。您应该会遇到编译失败。
  • @LightnessRacesinOrbit 即使返回类型不是函数签名的一部分?
  • @BЈовић 函数的签名无关;该程序显然调用了getInt,然后调用了getFloat,那么为什么getFloat 被调用了两次呢?
  • @LightnessRacesinOrbit 很奇怪。我编译了,getFloat() 没有被调用两次。 checkType(float x) 被调用了两次。

标签: c++ function c++11 map overloading


【解决方案1】:

正如您已经发现的那样,您实现它的方式是行不通的,因为存储在 map 中的函数返回浮点数。

正确的方法是使用类型擦除,但如果您使用 void*,则必须注意正确的转换。另一种选择是使用boost::anyQVariant

此示例使用const void* 擦除类型:

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

using namespace std;

void callForInt(const void* x){
    const int* realX = static_cast < const int* >( x );
    cout << "we got an int: " << *realX << endl;
}

void callForFloat(const void* x){
    const float* realX = static_cast < const float* >( x );
    cout << "we got a float: " << *realX << endl;
}

int main(){
   map<string, function<void(const void*)> > myMap({
      {"int", callForInt},
      {"float", callForFloat}
   });

   const int v1 = 1;
   const float v2 = -101.23f;

   myMap["int"](&v1);
   myMap["float"](&v2);
}

【讨论】:

  • 很公平,感谢您的回答。我的解决方案是类似的......虽然我对此有点菜鸟。我尝试使用 typeid(检查发送的类型)以及动态转换来检查哪个指针返回有效......如果这有任何意义。无论如何,目标是让映射函数接受相同的参数集,但返回不同的东西。由于映射函数总是返回 void 这并不能真正让我满意,但我理解这个问题并会接受你的回答。
  • @user1973454 使用boost::anyQVariant,您可以获得某种类型的安全性(如果您使用他们的转换,而不是 reinterpret_cast 或 c 样式转换)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 2015-10-08
  • 2021-11-17
  • 1970-01-01
相关资源
最近更新 更多