C++ 按返回类型重载
我在这里读到了一些关于这个话题的问题,这些问题让我感到困惑。我刚开始学习C++,还没有研究过模板或者操作符重载等等。 现在有没有一种简单的过载方法C++ 按返回类型重载,c++,overloading,C++,Overloading,我在这里读到了一些关于这个话题的问题,这些问题让我感到困惑。我刚开始学习C++,还没有研究过模板或者操作符重载等等。 现在有没有一种简单的过载方法 class My { public: int get(int); char get(int); } 没有模板或奇怪的行为?还是我应该 class My { public: int get_int(int); char get_char(int); } 不,没有。不能基于返回类型重载方法 重载解析将考虑函数签名。函数
class My {
public:
int get(int);
char get(int);
}
没有模板或奇怪的行为?还是我应该
class My {
public:
int get_int(int);
char get_char(int);
}
不,没有。不能基于返回类型重载方法 重载解析将考虑函数签名。函数签名由以下部分组成:
- 函数名
- cv限定符
- 参数类型
class My {
public:
int getInt(int);
char getChar(int);
};
2) 输出参数:
class My {
public:
void get(int, int&);
void get(int, char&);
}
3) 模板。。。在这种情况下,过度使用。在C++中,没有返回超载类型的方法。如果不使用模板,使用
get\u int
和get\u char
将是最好的选择。不,不能按返回类型重载;仅按参数类型和常量/易失性限定符
一种替代方法是使用引用参数“返回”:
void get(int, int&);
void get(int, char&);
尽管我可能会使用一个模板,或者像您的第二个示例那样使用不同名称的函数。您不能基于返回类型重载方法。最好是创建两个语法稍有不同的函数,例如在第二个代码段中。不能根据函数的返回类型重载函数。
您可以根据此函数所采用的参数类型和数量来进行覆盖。这是可能的,但我不确定这是否是我推荐的技术 初学者。与其他情况一样,当您希望函数的选择 根据返回值的使用方式,可以使用代理;首先定义 函数如
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();
}
};
根据需要将其扩展到多种类型。您可以这样想: 你有:
int get(int);
char get(int);
并且,在调用时收集函数的返回值不是强制性的
现在,你调用
get(10); -> there is an ambiguity here which function to invoke.
因此,如果基于返回类型允许重载,则没有任何意义。虽然关于此问题的大多数其他注释在技术上是正确的,但是如果将返回值与重载输入参数相结合,则可以有效地重载返回值。例如:
class My {
public:
int get(int);
char get(unsigned int);
};
演示:
恢复一个旧线程,但是我可以看到没有人提到ref限定符重载。Ref限定符是C++11中添加的一种语言功能,我最近才偶然发现它——它不像cv限定符那样广泛。其主要思想是区分这两种情况:在右值对象上调用成员函数时,以及在左值对象上调用成员函数时。您基本上可以编写如下内容(我正在稍微修改OP的代码):
当然,与cv限定符一样,这两个函数可能返回相同的类型,重载仍然会成功。我使用了James Kanze使用代理的答案: 我想避免在空白*上使用大量丑陋的静态_投射,所以我这样做了:
#包括
#包括
结构JoyDev{
私人:
联合{
SDL_GameController*dev_gc=nullptr;
SDL_操纵杆*dev_js;
};
公众:
运算符SDL_GameController*&(){return dev_gc;}
运算符SDL_*&(){return dev_js;}
SDL_GameController*&操作符=(SDL_GameController*p){dev_gc=p;返回dev_gc;}
SDL_操纵杆*&运算符=(SDL_操纵杆*p){dev_js=p;返回dev_js;}
};
结构状态{
公众:
乔伊德夫;
};
int main(int argc,字符**argv)
{
JoyState js;
js.dev=SDL_JoystickOpen(0);
js.dev=SDL_游戏控制器打开(0);
SDL_GameControllerRumble(js.dev,0xFFFF,0xFFFF,300);
返回0;
}
很好用 如前所述,在这种情况下,模板是多余的,但它仍然是一个值得一提的选项
class My {
public:
template<typename T> T get(int);
};
template<> int My::get<int>(int);
template<> char My::get<char>(int);
我的班级{
公众:
模板T-get(int);
};
模板int My::get(int);
模板char My::get(int);
只是为了确定:像模板T get(int)
这样的东西会起作用吗?是的,@Niklas,但如果你不使用其他模板功能,你必须称之为get
或get
,这对你来说并没有多大好处。@Rob:,如果您有类似于T get(T)
的内容,编译器可以确定T
。如果调用get('a')
,编译器会推断T
是char
,您不必显式调用get('a')
。我仍然不确定这是否是标准,尽管我认为是。仅供参考,GCC和Clang都支持这一点。这是非常标准的,@Netcoder,但这并不是编译器仅推导返回类型的情况,您认为这是可能的。在您的示例中,编译器推断出参数类型,一旦知道,它就会在其他任何地方填充T
的值,包括返回类型。我希望您在Niklas的第一条注释中给出一个编译器为函数推导T
的示例。您不能在返回类型上重载普通函数,但编译器将根据结果类型在转换运算符之间进行选择;您可以利用这一点来创建一个代理,该代理有效地充当返回类型重载的角色。@JeffPigarelli模板解决方案意味着成员模板:My::get(int)
。这是一个有效的选择,如果1)你必须处理很多不同的类型,都是w
I
C
#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..
class My {
public:
template<typename T> T get(int);
};
template<> int My::get<int>(int);
template<> char My::get<char>(int);