首页 > 解决方案 > 为什么我需要为传递给 Y 组合器的函数指定返回值

问题描述

我写了一个像这样的 Y 组合器:

template <class F>
struct Y{
  F f;
  Y(F _f) : f{_f} {}
  template<class...arg_t>
  auto operator()(arg_t&&...arg) {return f(*this,std::forward<arg_t>(arg)...);}
};

它有效,但是当我尝试定义阶乘时

auto fact = Y{[](auto&& self, int n) {
                if (n<=1) return 1;
                return n*self(n-1);}};

它会编译,但是当我像f(3)clang一样调用它时,会卡在推断返回类型上。使用显式返回类型,一切正常。这是模板扣除的限制吗?有解决办法吗?

标签: c++templatesfunctional-programmingtemplate-argument-deductiony-combinator

解决方案


我不相信有办法解决它。您创建一个具有以下定义的 lambda:

[](auto&& self, int n) {
            if (n<=1) return 1;
            return n*self(n-1);
 }

这转化为:

struct lambda
 {
  template <typename T1>
  constexpr auto operator()(T1&&self, int n) const
   {
            if (n<=1)
                  return 1;
            return n*self(n-1);
    }
};

鉴于该代码,您的编译器应该将返回类型推断为 2 个返回语句的通用类型。

使用您的模板 instation,它首先需要知道您的实例化的返回类型,然后才能计算该实例化的答案。

对于这种特定情况,可能仍然可以正确推断。如果您在两者之间添加额外的间接并重新使用您的类型会发生什么?


推荐阅读