我在这里读到了几个关于这个主题的问题,这个问题似乎让我感到困惑。我刚刚开始学习C ++,我还没有学过模板或运算符重载等等。
现在有一种简单的方法来重载
class My {
public:
int get(int);
char get(int);
}
没有模板或奇怪的行为?或者我应该
class My {
public:
int get_int(int);
char get_char(int);
}
答案 0 :(得分:89)
不,没有。您不能基于返回类型重载方法。
重载分辨率会考虑功能签名。函数签名由以下内容组成:
这是引用:
1.3.11签名
有关参与重载的函数的信息 resolution(13.3):它的参数类型列表(8.3.5),如果是 function是一个类成员,函数上的cv-qualifiers(如果有的话) 本身和声明成员函数的类。 [...]
选项:强>
1)更改方法名称:
class My {
public:
int getInt(int);
char getChar(int);
};
2)输出参数:
class My {
public:
void get(int, int&);
void get(int, char&);
}
3)模板......在这种情况下过度杀伤。
答案 1 :(得分:73)
这是可能的,但我不确定这是我推荐的技术
初学者。与其他情况一样,当您想要选择功能时
取决于如何使用返回值,您使用代理;首先定义
像getChar
和getInt
这样的函数,然后是通用的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();
}
};
根据需要将其扩展为多种类型。
答案 2 :(得分:8)
不,你不能通过返回类型重载;只能通过参数类型和const / volatile限定符。
一种替代方法是使用引用参数“返回”:
void get(int, int&);
void get(int, char&);
虽然我可能要么使用模板,要么使用不同命名的函数,例如你的第二个例子。
答案 3 :(得分:4)
你可以这样思考:
你有:
int get(int);
char get(int);
并且,在调用时不必强制收集函数的返回值。
现在,你调用
get(10); -> there is an ambiguity here which function to invoke.
所以,如果基于返回类型允许重载,则没有意义。
答案 4 :(得分:4)
正在恢复旧线程,但是我看不到有人提到ref限定符超载。引用限定词是C ++ 11中添加的一种语言功能,我最近才偶然发现它-它没有像简历限定词。主要思想是区分两种情况:何时在右值对象上调用成员函数,以及何时在左值对象上调用成员函数。您基本上可以编写如下代码(我在稍微修改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
}
此代码将产生以下输出:
returning int..
returning char..
当然,与cv-qualifiers一样,这两个函数都可能返回相同的类型,并且重载仍将成功。
答案 5 :(得分:4)
如前所述,模板在这种情况下是过大的,但是仍然值得一提。
class My {
public:
template<typename T> T get(int);
};
template<> int My::get<int>(int);
template<> char My::get<char>(int);
答案 6 :(得分:2)
C ++中的返回类型无法重载。如果不使用模板,使用get_int
和get_char
将是您可以做的最佳选择。
答案 7 :(得分:2)
您不能基于返回类型重载方法。最好的办法是创建两种语法略有不同的函数,例如在第二个代码片段中。
答案 8 :(得分:2)
虽然关于此问题的大多数其他评论在技术上都是正确的,但您可以有效重载返回值如果将其与重载输入参数结合使用。例如:
class My {
public:
int get(int);
char get(unsigned int);
};
样本:
#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) );
}
由此产生的结果是:
I
C
答案 9 :(得分:0)
您不能根据函数的返回类型重载函数。 您可以根据此函数所使用的参数的类型和数量进行操作。
答案 10 :(得分:0)
我通过代理使用了詹姆斯·坎泽的答案:
https://stackoverflow.com/a/9569120/262458
我想避免在void *上使用大量难看的static_cast,所以我这样做了:
#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;
}
完美工作!