为什么在“自动返回”功能中需要decltype?

时间:2012-11-28 07:36:42

标签: c++ c++11 auto decltype

考虑this code

#include <iostream>
#include <typeinfo>

using namespace std;

template<typename T1, typename T2>
auto add(T1 l, T2 r) -> decltype(l + r){
    return l + r;
}

class C {};

class B {};

class A {
public:
    C operator+(const B& b) {
        C c;
        return c;
    }
};


int main() {
    // Using add()
    A a;
    B b;
    auto c = add(a, b);

    cout << typeid(a).name() << endl;
    cout << typeid(b).name() << endl;
    cout << typeid(c).name() << endl;
    cout << endl;

    // Doing the same thing but not on a function
    A a2;
    B b2;
    auto c2 = a2 + b2;

    cout << typeid(a2).name() << endl;
    cout << typeid(b2).name() << endl;
    cout << typeid(c2).name() << endl;
}

我只是有一个非常简单的问题:为什么我需要将decltype()放在add()的后缀返回类型中,这与第二种方法(不使用{{}的方法不同1}})?

3 个答案:

答案 0 :(得分:8)

  

为什么我需要在后缀返回类型add()中放入decltype(),这与第二种方法(不使用add()的方法不同)?

因为这是C ++规则的一部分。解析器从左到右运行;在大多数情况下,如果尚未达到标识符,则解析器不知道它。标识符,如函数参数。

因此,如果使用表达式来确定返回值的类型,并且该表达式以某种方式使用参数,则必须将返回类型放在函数参数之后。

  

但我的观点是,为什么编译器在知道A + B返回C时会自动推断出返回类型?

因为这些是C ++的规则:函数必须在函数声明中直接指定返回类型。不允许编译器推导出它。

Yet.

答案 1 :(得分:1)

  

为什么我需要在后缀返回类型add()

中放入decltype()

因为您将模板函数的返回类型声明为auto,并且您需要在函数声明之后以某种方式指定返回类型。

您也可以这样指定:

auto add(T1 l, T2 r) -> C

但如果您将整数传递给该函数,那将无法正常工作。

我没有看到第二个添加函数,但如果你的意思是operator+,那么你为它指定了返回类型。

答案 2 :(得分:0)

您没有 - 您可以在返回类型规范中添加任何类型的内容。如果你的问题是“为什么编译器不能为我推断出正确的类型?”:我可以尝试一些情况,但至少它需要看到定义。在某些情况下,编译器已经 推导出返回类型:在lambdas中包含一个返回语句

   auto l = [](int i) { return i>0; };

IIRC有野心放松对这些返回类型声明的限制,例如:允许单行功能只有您建议的自动返回类型。