返回类型不是符号名称的一部分。这使得基于返回类型的函数的重载变得不可能。 这种方法背后的想法是什么?
答案 0 :(得分:3)
Bjarne Stroustrup作为1998年1月12日新闻组comp.lang.c ++中一篇文章的一部分给出的理由是
C ++不允许基于返回的重载解析的原因 类型(因此您需要在示例中使用显式限定 下面是我希望重载分辨率自下而上。对于 例如,您可以确定子表达式a + b的含义 考虑a + b所属的完整表达式。超载 虽然我知道如何使用返回类型,但分辨率可能很微妙 作为决议的一部分(阿达表示如何),我决定不这样做。结果是 在这个决定中,a + b表示a + b + c与a + b + d相同。
同意与否,这是设计决策的基本原理。
答案 1 :(得分:1)
您可以调用函数或方法并丢弃它的返回值。编译器应该如何确定应该调用哪个函数或方法?
int sum(int a, int b)
long sum(int a, int b)
sum(10, 20) // which one should be called?
答案 2 :(得分:1)
有鸡肉和鸡蛋。 重载规则不考虑返回类型,因此不属于函数签名。
虽然在签名中考虑返回类型似乎很容易,但规则在最不明确的情况下不可避免地变得复杂。
考虑相对无害的代码,例如:
foo(bar(x),bim(bam(y)));
答案 3 :(得分:0)
这个问题有一个非常简单的解决方案:模板:
template <typename T>
T sum(double a, double b)
{
return static_cast<T>(a+b);
}
你用sum<int>(5,6)
调用它,它会将结果转换为int。这是一个不好的例子,但有时候这很有用,就像着名的std::to_string
相反,它被称为from_string
(它不是标准的一部分),但返回值是您选择使用的模板。
根据使用type_traits
的类型,您甚至可以使用更好的方法来专门化实现。在C ++ 11中,您可以这样做:
template <typename T>
T sum(double a, double b)
{
if(std::is_same<double,T>::value) //if the type is double
return a+b;
else
return static_cast<T>(a+b);
}
虽然你必须为每个案件投。为了使这个更高级(并且解决了转换问题,只有当你开始涉及字符串和其他带有标量类型的类时才能理解),在C ++ 17中,你可以使用constexpr if
并消除这个问题:
template <typename T>
T sum(double a, double b)
{
if constexpr(std::is_same<double,T>::value) //if the type is double
return a+b;
else
return static_cast<T>(a+b);
}
在最后一个分支中,另一个分支没有区别,因为它将在编译时进行评估。所以没有铸造问题。
答案 4 :(得分:0)
其他人说得对,现在引入这个问题会产生比解决问题更多的问题。
目前这种方式是正确的,因为它具有逻辑意义:你说你将要调用的函数(按名称),以及你要给它的参数是什么;该功能负责告诉您可以获得的回报。
此外,能够以一种方式调用foo(1, 2)
,然后以另一种方式调用foo(1, 2)
,并获得两种完全不同的结果,将会非常混乱。这只是......错了!
我们会根据我们提供的功能来识别功能,而不是通过它为我们提供的功能。