代码之家  ›  专栏  ›  技术社区  ›  anon

C++通过返回类型选择函数[复制]

  •  4
  • anon  · 技术社区  · 16 年前

    这个问题已经有了答案:

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

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

    但不是

    double func();
    int func();
    

    在前者,很明显,在后者,它是矛盾的。是否有任何扩展,让我告诉C++选择哪种函数也可以使用返回类型?

    谢谢!

    9 回复  |  直到 9 年前
        1
  •  11
  •   jpalecek    16 年前

    同一作用域中不能有两个具有相同名称和签名(即参数类型)的函数。但是,您可以创建一个函数,该函数的行为取决于将结果分配给哪个变量,如:

    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
  •  9
  •   James McNellis    16 年前

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

    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>();
    
        3
  •  5
  •   Jon Cage    16 年前

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

        4
  •  1
  •   AnT stands with Russia    9 年前

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

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

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

    您可以使用此技术强制一行中的重载分辨率,尽管它看起来不太优雅

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

    同样,在这种情况下,您可以手动执行重载解析。C++没有基于返回类型的隐式重载解析的特性(除了上面的说明)。

        5
  •  0
  •   Svisstack    16 年前

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

        6
  •  0
  •   John Weldon user3678248    16 年前

    不,其实也很难实现。我依稀记得听说这是一个p-np问题。

        7
  •  0
  •   mingos    16 年前

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

    或者,做:

    struct myReturnType {
      int myInt;
      double myDouble;
    };
    
    myReturnType func() {
      ...
    }
    
        8
  •  0
  •   bta    16 年前

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

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

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

        9
  •  0
  •   Raindrop7    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