最近我在找一个想要使C++更多Haskell-y的朋友,我们想要一个基本上像这样的函数:
auto sum(auto a, auto b) {
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
显然我不能使用auto作为参数类型,所以我将其更改为:
template<class A, class B>
auto sum(A a, B b) {
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
但这也不起作用.我们最终意识到我们需要这个:
template<class A, class B>
auto sum(A a, B b) -> decltype(a + b) {
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,重点是什么?不decltype只是重复信息,因为编译器只能查看return语句?
我认为可能需要它,所以我们可以只包含一个头文件:
template<class A, class B>
auto sum(A a, B b) -> decltype(a + b);
Run Code Online (Sandbox Code Playgroud)
...但我们无论如何都不能使用这样的模板.
我考虑的另一件事是编译器可能更容易,但看起来它实际上会更难.
案例1:随着 decltype
decltype语句的类型案例2:没有 decltype
因此,考虑到这些事情,尾随返回类型的重点是decltype什么?
小智 38
如果我们有以下内容怎么办?
template<class A, class B, class C>
auto sum(A a, B b, C c) {
if (rand () == 0) return a + b;
// do something else...
return a + c;
}
Run Code Online (Sandbox Code Playgroud)
.. where a + b和a + c表达式产生不同类型的结果.编译器应该决定将该函数作为该函数的返回类型以及为什么?C++ 11 lambdas已经涵盖了这种情况,只要return语句可以推导为相同的类型就可以省略返回类型(需要NB标准引用,一些来源声称只允许一个返回表达式,这是一个gcc毛刺).
技术原因是C++允许定义和声明是分开的.
template<class A, class B>
auto sum(A a, B b) -> decltype(a + b);
template<class A, class B>
auto sum(A a, B b) -> decltype(a + b)
{
}
Run Code Online (Sandbox Code Playgroud)
模板的定义可能是在头中.或者它可能在另一个文件中,因此您在查看界面时不必浏览功能定义的页面和页面.
C++必须考虑所有可能性.将尾随返回类型限制为仅仅函数定义意味着您不能执行如下这样简单的操作:
template<class A, class B>
class Foo
{
auto sum(A a, B b) -> decltype(a + b);
}
template<class A, class B>
auto Foo<A, B>::sum(A a, B b) -> decltype(a + b)
{
}
Run Code Online (Sandbox Code Playgroud)
但我们无论如何都不能使用这样的模板.
首先,尾随返回类型不仅仅是模板事物.它们适用于所有功能.其次,说谁?这是完全合法的代码:
template<class A, class B>
auto sum(A a, B b) -> decltype(a + b);
template<class A, class B>
auto sum(A a, B b) -> decltype(a + b)
{
}
Run Code Online (Sandbox Code Playgroud)
模板的定义可能是在头中.或者它可能在另一个文件中,因此您在查看界面时不必浏览功能定义的页面和页面.
C++必须考虑所有可能性.将尾随返回类型限制为仅仅函数定义意味着您不能执行如下这样简单的操作:
template<class A, class B>
class Foo
{
auto sum(A a, B b) -> decltype(a + b);
}
template<class A, class B>
auto Foo<A, B>::sum(A a, B b) -> decltype(a + b)
{
}
Run Code Online (Sandbox Code Playgroud)
这对许多程序员来说相当普遍.想要以这种方式编码没有任何问题.
lambda在没有返回类型的情况下离开的唯一原因是因为它们必须具有使用定义定义的函数体.如果将尾随返回类型限制为仅定义可用的那些函数,则无法使用上述任何一种情况.
没有技术理由说明为什么不可能.他们没有的主要原因是因为C++语言移动速度非常慢,并且需要很长时间才能添加功能.
你几乎可以用lambdas获得你想要的漂亮语法(但你不能在lambdas中使用templacised参数,再次没有充分的理由).
auto foo = [](int a, double b)
{
return a + b;
};
Run Code Online (Sandbox Code Playgroud)
是的,在某些情况下无法自动推断出返回类型.就像在lambda中一样,可能只需要在那些不明确的情况下自己声明返回类型.
目前,这些限制非常随意,令人非常沮丧.另请参阅删除概念以增加挫败感.
| 归档时间: |
|
| 查看次数: |
5536 次 |
| 最近记录: |