C++ 按返回类型重载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9568852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:59:55  来源:igfitidea点击:

Overloading by return type

c++overloading

提问by Shoe

I read few questions here on SO about this topic which seems yet confusing to me. I've just begun to learn C++ and I haven't studied templates yet or operator overloading and such.

我在这里阅读了一些关于这个主题的问题,这对我来说似乎还很困惑。我刚刚开始学习 C++,还没有研究过模板或运算符重载等。

Now is there a simple way to overload

现在有一个简单的方法来重载

class My {
public:
    int get(int);
    char get(int);
}

without templates or strange behavior? or should I just

没有模板或奇怪的行为?或者我应该只是

class My {
public:
    int get_int(int);
    char get_char(int);
}

?

?

回答by Luchian Grigore

No there isn't. You can't overload methods based on return type.

不,没有。您不能根据返回类型重载方法。

Overload resolution takes into account the function signature. A function signature is made up of:

重载解析考虑了函数签名。函数签名由以下部分组成:

  • function name
  • cv-qualifiers
  • parameter types
  • 函数名
  • cv-限定符
  • 参数类型

And here's the quote:

这是报价:

1.3.11 signature

1.3.11 签名

the information about a function that participates in overload resolution (13.3): its parameter-type-list (8.3.5) and, if the function is a class member, the cv-qualifiers (if any) on the function itself and the class in which the member function is declared. [...]

有关参与重载决议 (13.3) 的函数的信息:其参数类型列表 (8.3.5) 以及函数本身和类上的 cv 限定符(如果有)(如果该函数是类成员)其中声明了成员函数。[...]

Options:

选项:

1) change the method name:

1)更改方法名称:

class My {
public:
    int getInt(int);
    char getChar(int);
};

2) out parameter:

2)输出参数:

class My {
public:
    void get(int, int&);
    void get(int, char&);
}

3) templates... overkill in this case.

3)模板......在这种情况下太过分了。

回答by James Kanze

It's possible, but I'm not sure that it's a technique I'd recommend for beginners. As in other cases, when you want the choice of functions to depend on how the return value is used, you use a proxy; first define functions like getCharand getInt, then a generic get()which returns a Proxy like this:

这是可能的,但我不确定这是我向初学者推荐的技术。与其他情况一样,当您希望函数的选择取决于返回值的使用方式时,您可以使用代理;首先定义像getCharandgetInt这样的函数,然后定义一个泛型get(),它返回一个像这样的代理:

class Proxy
{
    My const* myOwner;
public:
    Proxy( My const* owner ) : myOwner( owner ) {}
    operator int() const
    {
        return myOwner->getInt();
    }
    operator char() const
    {
        return myOwner->getChar();
    }
};

Extend it to as many types as you need.

根据需要将其扩展为多种类型。

回答by Mike Seymour

No, you can't overload by return type; only by parameter types, and const/volatile qualifiers.

不,您不能按返回类型重载;仅按参数类型和 const/volatile 限定符。

One alternative would be to "return" using a reference argument:

一种替代方法是使用引用参数“返回”:

void get(int, int&);
void get(int, char&);

although I would probably either use a template, or differently-named functions like your second example.

尽管我可能会使用模板或不同名称的函数,例如您的第二个示例。

回答by Whoami

You can think this way:

你可以这样想:

You have:

你有:

  int get(int);
  char get(int);

And, it is not mandatory to collect the return value of the function while invoking.

并且,在调用时收集函数的返回值不是强制性的。

Now, You invoke

现在,你调用

  get(10);  -> there is an ambiguity here which function to invoke. 

So, No meaning if overloading is allowed based on the return type.

因此,如果根据返回类型允许重载,则没有意义。

回答by codechimp

While most of the other comments on this problem are technically correct, you can effectivelyoverload the return value ifyou combine it with overloading input parameter. For example:

虽然关于此问题的大多数其他评论在技术上是正确的,但如果将返回值与重载输入参数结合使用,则可以有效地重载返回值。例如:

class My {
public:
    int  get(int);
    char get(unsigned int);
};

DEMO:

演示:

#include <stdio.h>

class My {
public:
    int  get(         int x) { return 'I';  };
    char get(unsinged int x) { return 'C';  };
};

int main() {

    int i;
    My test;

    printf( "%c\n", test.get(               i) );
    printf( "%c\n", test.get((unsigned int) i) );
}

The resulting out of this is:

由此产生的结果是:

I 
C

回答by Miljen Mikic

Resurrecting an old thread, but I can see that nobody mentioned overloading by ref-qualifiers. Ref-qualifiers are a language feature added in C++11 and I only recently stumbled upon it - it's not so widespread as e.g. cv-qualifiers. The main idea is to distinguish between the two cases: when the member function is called on an rvalue object, and when is called on an lvalue object. You can basically write something like this (I am slightly modifying OP's code):

复活一个旧线程,但我可以看到没有人提到引用限定符的重载。引用限定符是 C++11 中添加的语言功能,我最近才偶然发现它 - 它不像 cv 限定符那样广泛。主要思想是区分两种情况:在右值对象上调用成员函数时,以及在左值对象上调用时。你基本上可以写这样的东西(我稍微修改了 OP 的代码):

#include <stdio.h>

class My {
public:
    int get(int) & { // notice &
        printf("returning int..\n");
        return 42;
    }
    char get(int) && { // notice &&
        printf("returning char..\n");
        return 'x';
    };
};

int main() {
    My oh_my;
    oh_my.get(13); // 'oh_my' is an lvalue
    My().get(13); // 'My()' is a temporary, i.e. an rvalue
}

This code will produce the following output:

此代码将产生以下输出:

returning int..
returning char..

Of course, as is the case with cv-qualifiers, both function could have returned the same type and overloading would still be successful.

当然,就像 cv 限定符的情况一样,两个函数都可以返回相同的类型并且重载仍然会成功。

回答by Frecklefoot

You can't overload methods based on return types. Your best bet is to create two functions with slightly different syntax, such as in your second code snippet.

您不能基于返回类型重载方法。最好的办法是创建两个语法略有不同的函数,例如在第二个代码片段中。

回答by sepp2k

There is no way to overload by return type in C++. Without using templates, using get_intand get_charwill be the best you can do.

在 C++ 中无法通过返回类型进行重载。不使用模板,使用get_intget_char将是您能做的最好的事情。

回答by AlexDan

you can't overload a function based on the return type of the function. you can overlead based on the type and number of arguments that this function takes.

您不能根据函数的返回类型重载函数。您可以根据此函数采用的参数类型和数量进行覆盖。

回答by Rafael Kitover

I used James Kanze's answer using a proxy:

我使用代理使用了 James Kanze 的回答:

https://stackoverflow.com/a/9569120/262458

https://stackoverflow.com/a/9569120/262458

I wanted to avoid using lots of ugly static_casts on a void*, so I did this:

我想避免在 void* 上使用大量丑陋的 static_casts,所以我这样做了:

#include <SDL_joystick.h>
#include <SDL_gamecontroller.h>

struct JoyDev {
    private:
        union {
            SDL_GameController* dev_gc = nullptr;
            SDL_Joystick*       dev_js;
        };
    public:
        operator SDL_GameController*&() { return dev_gc; }
        operator SDL_Joystick*&()       { return dev_js; }

        SDL_GameController*& operator=(SDL_GameController* p) { dev_gc = p; return dev_gc; }
        SDL_Joystick*&       operator=(SDL_Joystick* p)       { dev_js = p; return dev_js; }
};

struct JoyState {
    public:
        JoyDev dev;
};

int main(int argc, char** argv)
{
    JoyState js;

    js.dev = SDL_JoystickOpen(0);

    js.dev = SDL_GameControllerOpen(0);

    SDL_GameControllerRumble(js.dev, 0xFFFF, 0xFFFF, 300);

    return 0;
}

Works perfectly!

完美运行!