为什么函数的返回值不是符号名称的一部分

时间:2017-03-28 12:38:54

标签: c++

返回类型不是符号名称的一部分。这使得基于返回类型的函数的重载变得不可能。 这种方法背后的想法是什么?

5 个答案:

答案 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),并获得两种完全不同的结果,将会非常混乱。这只是......错了!

我们会根据我们提供的功能来识别功能,而不是通过它为我们提供的功能。