c++ - 为什么我需要为传递给 Y 组合器的函数指定返回值

标签 c++ templates functional-programming template-argument-deduction y-combinator

我写了一个像这样的 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 在推导返回类型时卡住了。使用显式返回类型,一切正常。这是模板推导的限制吗?有解决方法吗?

最佳答案

我不认为有解决办法。您使用以下定义创建一个 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 个返回语句的通用类型。

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

对于这种特定情况,仍有可能正确推断。如果您在两者之间添加额外的间接寻址并追溯回您的类型,会发生什么情况?

关于c++ - 为什么我需要为传递给 Y 组合器的函数指定返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53894280/

相关文章:

c++ - 如何在 C++ 中打印 char 指针的所有指针值?

C++11 std::function 比虚拟调用慢?

c++ - wchar_t 和编码

c++ - 模板类前向声明

windows - 在 bat 中处理文件

ajax - 在服务器和客户端之间共享 mustache/mustache 模板。 ASP.NET MVC

javascript - 使用 `Task` 将 `Some` 从 `Left` 转换或过滤到 `fp-ts`

c++ - Nsight Eclipse 找不到共享库

php - 使用 array_map() 访问一级键而不调用 `array_keys()`

swift - 如何在 Swift 中将 "append"设置为不可变字典?