【发布时间】:2023-03-18 06:16:01
【问题描述】:
最近我和一个朋友一起工作,他想让 C++ 更像 Haskell-y,我们想要一个基本上像这样的函数:
auto sum(auto a, auto b) {
return a + b;
}
显然我不能使用auto作为参数类型,所以我改成这样:
template<class A, class B>
auto sum(A a, B b) {
return a + b;
}
但这也不起作用。我们最终意识到我们需要这个:
template<class A, class B>
auto sum(A a, B b) -> decltype(a + b) {
return a + b;
}
所以我的问题是,有什么意义? decltype 不就是重复信息,因为编译器只能看return语句吗?
我认为可能需要它,所以我们可以只包含一个头文件:
template<class A, class B>
auto sum(A a, B b) -> decltype(a + b);
...但无论如何我们都不能使用这样的模板。
我考虑的另一件事是编译器可能更容易,但似乎实际上会更难。
案例一:decltype
- 找出
decltype语句的类型 - 找出任何返回值的类型
- 看看它们是否匹配
案例2:没有decltype
- 找出任何返回值的类型
- 看看它们是否匹配
考虑到这些,decltype 的尾随返回类型有什么意义?
【问题讨论】:
-
我认为这是因为函数的所有类型信息都必须从声明中知道(不包括函数体),而不需要经过定义。
-
我认为这个问题最好用“为什么我们需要尾随返回类型?”来表述。它们只是
decltype的一个用例,问题与其他任何一个都没有关系。 -
@LucDanton 对,所以应该是“为什么我们不能自动推断返回类型?”
-
@Brendan:简单的回答是可以,但委员会明确或暗示认为不值得付出努力。 C++ 已经是一种过于复杂的语言,添加规则来实现这一点是可能的,但会增加更多的复杂性。也就是说,我同意能够说
auto foo(auto x, auto y) { return x + y;}会很好,这当然是可能的,但它与额外的语法一样可行,只是更烦人;烦恼比新规则更容易处理。也就是说,非常不幸的是,他们没有详细说明推断 lambda 之类的返回类型。 -
我知道现在已经很晚了,但是 GCC 4.8.0 使用
-std=c++1y选项对此提供了支持。目前正在提议中。