【问题标题】:C++ choose function by return type [duplicate]C ++按返回类型选择函数[重复]
【发布时间】:2010-04-26 22:57:22
【问题描述】:

我意识到标准 C++ 仅按参数类型选择函数,而不是返回类型。即我可以这样做:

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

但不是

double func();
int func();

在前者中,很清楚,在后者中,它是模棱两可的。是否有任何扩展可以让我告诉 C++ 通过返回类型来选择要使用的函数?

谢谢!

【问题讨论】:

标签: c++ function polymorphism


【解决方案1】:

您不能在同一范围内拥有两个具有相同名称和签名(即参数类型)的函数。然而,您可以创建一个行为不同的函数,具体取决于您将结果分配给哪个变量,如下所示:

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

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

【讨论】:

    【解决方案2】:

    如果你有这两个函数,如果你只是调用,编译器应该选择哪一个:

    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>();
    

    【讨论】:

    • 我同意你的观点,但应该可以在你调用int i = func(); 的情况下实现,并且只在没有void 函数和func() 时给出错误被调用时没有伴随的赋值。不过我不喜欢那样。
    【解决方案3】:

    为什么不换个名字呢?如果他们返回不同的东西,我觉得他们可能在不同的事情。为什么要混淆您的代码?

    【讨论】:

    • 你同意返回类型在函数重载中不太重要吗?
    • 我认为以最适合方法正在执行的操作的任何形式返回数据很重要(即,如果它是数值,则适当的精度)。如果您的方法正在计算最接近的整数,则将其原样返回并使用 static_cast 声明您很乐意转换为另一种类型,如果这是您在调用代码中需要的。
    • 如果您的方法以浮点数的形式计算某些精度,则将其返回,由调用者决定如何适当处理删除小数部分(舍入、下限、上限等) )。至少,作为调用者,你不会对从方法中得到的结果抱有任何幻想..
    【解决方案4】:

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

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

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

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

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

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

    【讨论】:

    • 这正是我想要的。谢谢!
    【解决方案5】:

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

    【讨论】:

    • 糟糕的编译器无法确定收集结果的变量的类型……
    • @JoanCharmant:在您看来,当编译器看到auto result = func(); 时应该怎么做? result 应该是什么类型?类型可以明确确定吗?
    【解决方案6】:

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

    【讨论】:

      【解决方案7】:

      据我所知没有。您最好为函数命名不同的名称,或者使用不同的参数让编译器(而不是您)区分它们。

      或者,做:

      struct myReturnType {
        int myInt;
        double myDouble;
      };
      
      myReturnType func() {
        ...
      }
      

      【讨论】:

        【解决方案8】:

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

        typedef union {
          double d;
          int    i;
        } my_union;
        
        my_union func();
        

        但是,这需要函数和调用者以某种方式知道预期的数据类型,并且可能导致各种错误。你可以这样做,但我绝对不会推荐它。

        【讨论】:

          【解决方案9】:

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

          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
          

          【讨论】:

            猜你喜欢
            • 2014-09-06
            • 2013-07-29
            • 2011-05-16
            • 1970-01-01
            • 1970-01-01
            • 2019-08-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多