C ++按返回类型选择函数

时间:2010-04-26 22:57:23

标签: c++ function polymorphism

我意识到标准C ++只能通过参数类型选择函数,而不是返回类型。我可以做类似的事情:

void func(int);
void func(double);

但不是

double func();
int func();

在前者中,很清楚,在后者中,它是暧昧的。是否有任何扩展允许我告诉C ++选择哪个函数也可以使用返回类型?

谢谢!

9 个答案:

答案 0 :(得分:11)

在同一范围内,不能有两个具有相同名称和签名的函数(即参数类型)。然而,您可以根据分配结果的变量创建一个行为不同的函数,如:

int x=f();
double x=f(); // different behaviour from above

使f()返回带有重载强制转换运算符的代理。

struct Proxy
{
  operator double() const { return 1.1; }
  operator int() const { return 2; }
};

Proxy f()
{
  return Proxy();
}

请参阅http://ideone.com/ehUM1

不是这个特定的用例(返回不同的数字)是有用的,但在那里 是这个成语的用途。

答案 1 :(得分:9)

如果您有这两个函数,如果您只是调用了编译器,那么应​​该选择哪个函数:

func();

您最接近要求的是使用专门的功能模板(请注意you want to be very careful when specializing function templates):

template <typename ReturnT>
ReturnT func();

template <>
double func<>() { return 42; }

template <>
int func<>() { return 0; }

然后你可以按如下方式调用它:

func<int>();
func<double>();

答案 2 :(得分:5)

为什么不以不同的方式命名?如果他们回归不同的东西,那对我来说就好像他们可能不同的事情。为什么要混淆你的代码?

答案 3 :(得分:1)

C ++中有一个上下文,其中重载决策的结果取决于表达式左侧的“返回类型”。它是函数指针值的初始化/赋值与函数的地址。它适用于左手大小的显式对象以及由显式类型转换创建的临时对象。

在您的情况下,它可用于从两个重载的函数中选择一个特定函数。例如:

int (*pfunc)() = func; // selects `int func()`
int i = pfunc(); // calls `int func()`

您可以使用此技术在一行中强制重载解析,尽管它看起来不太优雅

int i = ((int (*)()) func)(); // selects and calls `int func()`

同样,在这种情况下,您手动执行重载决策。 C ++没有任何特性会导致基于返回类型的隐式重载解析(除了我上面说明的内容)。

答案 4 :(得分:0)

因为编译器不知道你调用了什么函数!

答案 5 :(得分:0)

没有;它实际上也很难实现。我依稀记得听说这是一个P-NP问题。

答案 6 :(得分:0)

我不知道。你最好用不同的方式命名函数,或者使用不同的参数让编译器(不是你)区分它们。

或者,执行:

struct myReturnType {
  int myInt;
  double myDouble;
};

myReturnType func() {
  ...
}

答案 7 :(得分:0)

这有点危险,但您可以创建要返回的不同类型的并集,并将这两者组合成一个返回union的函数。例如:

typedef union {
  double d;
  int    i;
} my_union;

my_union func();

但是,这将要求函数和调用者以某种方式知道结果所期望的数据类型,并且可能导致各种错误。你可以做到这一点,但我绝对不会推荐它。

答案 8 :(得分:0)

函数重载需要每个表单的不同签名,不包括返回类型。两个或多个表格是正确的,只要它们在列表中的参数数量或至少一种类型或参数的顺序不同,例如:

void print();  // 1
void print(int, char); // 2  ok number of parameters
void print(char, int); // 3  ok the order of parameters type
int  print(int, char); // 4  no the same signature as 2 except the return type