考虑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}})?
答案 0 :(得分:8)
为什么我需要在后缀返回类型add()中放入decltype(),这与第二种方法(不使用add()的方法不同)?
因为这是C ++规则的一部分。解析器从左到右运行;在大多数情况下,如果尚未达到标识符,则解析器不知道它。标识符,如函数参数。
因此,如果使用表达式来确定返回值的类型,并且该表达式以某种方式使用参数,则必须将返回类型放在函数参数之后。
但我的观点是,为什么编译器在知道A + B返回C时会自动推断出返回类型?
因为这些是C ++的规则:函数必须在函数声明中直接指定返回类型。不允许编译器推导出它。
答案 1 :(得分:1)
为什么我需要在后缀返回类型add()
中放入decltype()
因为您将模板函数的返回类型声明为auto
,并且您需要在函数声明之后以某种方式指定返回类型。
您也可以这样指定:
auto add(T1 l, T2 r) -> C
但如果您将整数传递给该函数,那将无法正常工作。
我没有看到第二个添加函数,但如果你的意思是operator+
,那么你为它指定了返回类型。
答案 2 :(得分:0)
您没有 - 您可以在返回类型规范中添加任何类型的内容。如果你的问题是“为什么编译器不能为我推断出正确的类型?”:我可以尝试一些情况,但至少它需要看到定义。在某些情况下,编译器已经 推导出返回类型:在lambdas中包含一个返回语句
auto l = [](int i) { return i>0; };
IIRC有野心放松对这些返回类型声明的限制,例如:允许单行功能只有您建议的自动返回类型。