Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ lambda的深递归_C++_Lambda - Fatal编程技术网

C++ lambda的深递归

C++ lambda的深递归,c++,lambda,C++,Lambda,我有一个由N级循环组成的程序。但N不是固定的,所以我使用模板来帮助。逻辑如下 #include <type_traits> void do_something1() {} void do_something2() {} enum Case { one, two }; struct loop { template<int N, Case case_, typename Lambda> std::enable_if_t < (0 < N) >

我有一个由N级循环组成的程序。但N不是固定的,所以我使用模板来帮助。逻辑如下

#include <type_traits>

void do_something1() {}
void do_something2() {}
enum Case { one, two };
struct loop {
    template<int N, Case case_, typename Lambda>
    std::enable_if_t < (0 < N) > func(Lambda&& visit) const {
        //return directly in some cases, so complexity is not a problem

        func<N - 1, one>([&visit] {
            do_something1();// depend on the results of func<N - 1, one>
            visit();
        });

        func<N - 1, two>([&visit] {
            do_something2();// depend on the results of func<N - 1, two>
            visit();
        });
    }
    template<int N, Case case_, typename Lambda>
    std::enable_if_t < (0 == N) > func(Lambda&& visit) const {
        visit();
    }
};

int main() {
    loop{}.func<32, one>([] {});

    return 0;
}

但是,由于深度递归,这将无法编译。在我看来,是内联和func中的两个分支导致了这个问题。那么,有没有一种有效的方法来解决这个问题呢?

内联可以解决运行时的复杂性。提前返回也解决了运行时的复杂性。但是,编译器错误是因为您具有编译时复杂性。即使是无法访问的代码也必须编译

如果编译器将其内联,那么该代码将具有巨大的复杂性。这两个分支都是内联的,这意味着f的//return-early-check在f中内联两次,f的//return-early-check在f中内联两次,因此在f中内联4次,因此f将内联大约40亿次。任何一个好的编译器都不应该有这样的问题;它应该跳过内联


简单的解决方法是去掉Case,反正它不使用,并使N成为正则变量。一个更复杂的方法是在运行时检查变量N是否有一些小的常量值Nc,然后才调用该函数的模板化版本。通过选择Nc,您可以限制模板实例化深度。

您有2**32个函数调用要访问和函数实例化…@Jarod42我认为有4*32个访问,即每个N和case。在模板参数中,如果添加括号,比较会更清楚:std::enable_if_t0>@MSalters谢谢,我已经编辑过了。@user1535111:Jarod是对的。有4*32个不同的实例化,但较低级别的实例化可以通过多个路径实现。因此,内联确实需要考虑40亿个函数调用。在这种情况下,是否有可能迫使编译器逐步实例化F?如中所示,首先实例化f,然后实例化f,然后实例化f等等,以避免内联函数的指数增长?实例化决策与内联决策是分开的,因此可以实例化f,但这不一定能解决您的问题。但是,我会考虑使用分而治之算法。使用调用func的lambda并将其传递给func!您可能需要进行ifN%2测试,但即使是对ifN也会进行优化。