返回未知类型的函数

Jac*_*cob 8 c++ variant visual-c++-2005

class Test
{
public:

 SOMETHING DoIt(int a)
 {
  float FLOAT = 1.2;
  int INT = 2;
  char CHAR = 'a';

  switch(a)
  {
  case 1: return INT;
  case 2: return FLOAT;
  case 3: return CHAR;
  }
 }
};


int main(int argc, char* argv[])
{  
 Test obj;
 cout<<obj.DoIt(1);    
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现在,使用a = 1意味着我需要返回一个整数等的知识,无论如何Doit()可以返回变量数据类型的变量吗?

从本质上讲,我该如何取代SOMETHING

PS:我正在尝试寻找一种替代方法来返回包含这些数据类型的结构/联合.

Ara*_*raK 25

你可以使用boost::anyboost::variant做你想做的事.我建议,boost::variant因为您知道要返回的类型集合.


这是一个非常简单的例子,尽管你可以做更多的事情variant.查看参考资料以获取更多示例:)

#include "boost/variant.hpp"
#include <iostream>

typedef boost::variant<char, int, double> myvariant;

myvariant fun(int value)
{
 if(value == 0)
 {
  return 1001;
 }
 else if(value  == 1)
 {
  return 3.2;
 }
  return 'V';
}

int main()
{
 myvariant v = fun(0);
 std::cout << v << std::endl;

 v = fun(1);
 std::cout << v << std::endl;

 v = fun(54151);
 std::cout << v << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

输出:

1001
3.2
V
Run Code Online (Sandbox Code Playgroud)

我会使用boost::variant而不是union因为你不能在里面使用非POD类型union.此外,boost::any如果您不知道您正在处理的类型,那就太棒了.否则,我会使用,boost::variant因为它更有效,更安全.


回答编辑过的问题:如果您不想Boost附带代码,请查看bcp.bcp来自同一链接的描述:

bcp实用程序是一个用于提取Boost子集的工具,它对于希望与Boost分开分发其库的Boost作者以及希望将Boost子集与其应用程序一起分发的Boost用户非常有用.

bcp还可以报告您的代码所依赖的Boost的哪些部分,以及这些依赖项使用的许可证.


小智 8

C++是一种强类型语言,没有未知类型的概念.你可以尝试使用boost :: any,它可以(有点)指定任何类型.不过,我会质疑你的功能设计.

  • @Jacob您在这里得到的答案质量与问题的细节成正比. (3认同)
  • @Neil虽然我知道这里有代码味道.我不明白你如何在不了解设计的情况下对设计提出疑问.我在为我的一个大学课程建立词法分析器时使用了boost :: variant,在我看来它是正确的工具.即使C++是一种强类型语言,在我看来并不意味着一直使用variant或者任何来自boost的错误. (2认同)
  • @Arak我说我会质疑他的设计 - 但他似乎并不想回答.问题的确意味着 - "请解释为什么你认为这是一个很好的解决方案?" 所有的设计都应该受到质疑. (2认同)
  • 所有这些答案都可能会陷入局部最低限度,真正的答案就在其他地方.虽然`boost :: any`或`boost :: variant`可能是返回不同类型的最佳方法,但返回不同类型可能不是解决特定问题的最佳方法. (2认同)

Kir*_*sky 5

如果您在编译时知道类型,则可以使用模板.如果type取决于运行时,则不能使用模板.

class Test
{
  template<int> struct Int2Type {};
  template<>    struct Int2Type<1> { typedef int value_type; };
  template<>    struct Int2Type<2> { typedef float value_type; };
  template<>    struct Int2Type<3> { typedef char value_type; };

public:
  template<int x> typename Int2Type<x>::value_type DoIt() {}; // error if unknown type used
  template<> typename Int2Type<1>::value_type DoIt<1>() { return 2; };
  template<> typename Int2Type<2>::value_type DoIt<2>() { return 1.2f; };
  template<> typename Int2Type<3>::value_type DoIt<3>() { return 'a'; };
};

int main()
{
  Test obj;
  cout << obj.DoIt<2>(); 
  return 0;
}
Run Code Online (Sandbox Code Playgroud)