我在这里读到了几个关于这个主题的问题,这个问题似乎让我感到困惑.我刚刚开始学习C++,我还没有学过模板或运算符重载等等.
现在有一种简单的重载方式
class My {
public:
int get(int);
char get(int);
}
Run Code Online (Sandbox Code Playgroud)
没有模板或奇怪的行为?或者我应该
class My {
public:
int get_int(int);
char get_char(int);
}
Run Code Online (Sandbox Code Playgroud)
?
Luc*_*ore 94
不,没有.您不能基于返回类型重载方法.
重载分辨率考虑了功能签名.功能签名由以下部分组成:
这是引用:
1.3.11签名
有关参与重载决策的函数的信息(13.3):它的参数类型列表(8.3.5),如果函数是类成员,函数本身和类的cv限定符(如果有的话)其中声明了成员函数.[...]
选项:
1)更改方法名称:
class My {
public:
int getInt(int);
char getChar(int);
};
Run Code Online (Sandbox Code Playgroud)
2)输出参数:
class My {
public:
void get(int, int&);
void get(int, char&);
}
Run Code Online (Sandbox Code Playgroud)
3)模板......在这种情况下过度杀伤.
Jam*_*nze 74
这是可能的,但我不确定这是我为初学者推荐的技术.与其他情况一样,当您希望函数的选择取决于返回值的使用方式时,您可以使用代理; 首先定义像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();
}
};
Run Code Online (Sandbox Code Playgroud)
根据需要将其扩展为多种类型.
不,你不能通过返回类型重载; 仅通过参数类型和const/volatile限定符.
一种替代方法是使用引用参数"返回":
void get(int, int&);
void get(int, char&);
Run Code Online (Sandbox Code Playgroud)
虽然我可能会使用模板,或者像第二个例子那样使用不同名称的函数.
您可以这样想:
你有:
int get(int);
char get(int);
Run Code Online (Sandbox Code Playgroud)
并且,在调用时不强制收集函数的返回值。
现在,您调用
get(10); -> there is an ambiguity here which function to invoke.
Run Code Online (Sandbox Code Playgroud)
因此,如果根据返回类型允许重载,则没有意义。
复活一个旧线程,但我可以看到没有人提到引用限定符的重载。引用限定符是 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
}
Run Code Online (Sandbox Code Playgroud)
此代码将产生以下输出:
returning int..
returning char..
Run Code Online (Sandbox Code Playgroud)
当然,与 cv 限定符的情况一样,两个函数都可以返回相同的类型并且重载仍然会成功。
如前所述,在这种情况下,模板有点矫枉过正,但它仍然是一个值得一提的选项。
class My {
public:
template<typename T> T get(int);
};
template<> int My::get<int>(int);
template<> char My::get<char>(int);
Run Code Online (Sandbox Code Playgroud)