简体   繁体   English

斐波那契中的模板递归如何在 c++ 中工作?

[英]How does template recursion in fibonacci work in c++?

For a homework assignement I need to make a Fibonacci struct that uses a template with a single integer input and makes use of template specialisation.对于家庭作业,我需要制作一个斐波那契结构,该结构使用带有单个 integer 输入的模板并使用模板专业化。 Online I found what I needed to make, but I couldn't have made it myself.在网上我找到了我需要做的东西,但我自己做不到。 I feel quite bad, since I don't really understand how it exactly works.我感觉很糟糕,因为我真的不明白它是如何工作的。

I have trouble with thinking in terms of templates.我在考虑模板方面遇到了麻烦。 When I read about the fibonacci algorithm I thought this could be easily done with loops, but that is not allowed for the assignment.当我读到斐波那契算法时,我认为这可以通过循环轻松完成,但分配不允许这样做。

The biggest advantage of a template is (what I've read so far): "a template allows to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type."模板的最大优点是(到目前为止我已经读过):“模板允许创建 function 模板,其功能可以适应多种类型或 class,而无需为每种类型重复整个代码。”

I understand what the following part does:我了解以下部分的作用:

   template<>
    struct fibonacci<0>
    {
        static const int value = 0;
    };

    template<>
    struct fibonacci<1>
    {
        static const int value = 1;
    };

When fibonacci<0> or fibonacci<1> is called, the variable value is set to 0 or 1. The main confusion is in the part:当调用 fibonacci<0> 或 fibonacci<1> 时,变量值设置为 0 或 1。主要混淆在以下部分:

 template<int n>
    struct fibonacci
    {
        static const int value = fibonacci<n - 1>::value + fibonacci<n - 2>::value;
    };

Questions about individual parts:关于个别部分的问题:

template<int n> 

Is it correct to assume that this part indicates that only integer values are allowed in the struct?假设这部分表明结构中只允许 integer 值是否正确?

static const int value

Why is it necessary to put static const in front of the int value ?为什么必须将static const放在int value前面?

fibonacci<n - 1>::value

Here recursion is used, so I assume that for example n = 3 the fibonacci<2> and fibonacci<1> will be called.这里使用了递归,所以我假设例如 n = 3 fibonacci<2> 和 fibonacci<1> 将被调用。 For the fibonacci<2> the fibonacci<1> and fibonacci<0> will be called.对于斐波那契<2>,将调用斐波那契<1> 和斐波那契<0>。 So for every int n (until overflow) it will apply recursion until the template specialization.因此,对于每个 int n (直到溢出),它将应用递归直到模板特化。 I don't really understand the ::value part.我不太了解::value部分。 What does happen here?这里会发生什么?

The whole fibonacci struct:整个斐波那契结构:

 template<int n>
    struct fibonacci
    {
        static const int value = fibonacci<n - 1>::value + fibonacci<n - 2>::value;
    };

    template<>
    struct fibonacci<0>
    {
        static const int value = 0;
    };

    template<>
    struct fibonacci<1>
    {
        static const int value = 1;
    };

I usually think of templates as an indicator for the precompiler to copy and paste a chunk of code, while changing a specific element indicated by <> .我通常将模板视为预编译器复制和粘贴代码块的指示器,同时更改由<>指示的特定元素。

You can experiment with it but if a template is never called in the body of your file, then you will see that the precompiler does not even include the template (essentially it dissapears from your code).您可以尝试使用它,但如果从未在文件正文中调用模板,那么您将看到预编译器甚至不包含模板(基本上它从您的代码中消失了)。

If you are curious what happens at this pre-processing stage add the -E flag to your g++ compilation.如果您好奇在这个预处理阶段会发生什么,请将-E标志添加到您的 g++ 编译中。 g++ -E yourFile.cpp . g++ -E yourFile.cpp If you want to capture the output in a file do g++ -E yourFile.cpp >> file如果要在文件中捕获 output,请执行g++ -E yourFile.cpp >> file

Answers:答案:

To answer your questions:要回答您的问题:

  1. Is it correct to assume that this part indicates that only integer values are allowed in the struct?假设这部分表明结构中只允许 integer 值是否正确?

<int n> is showing the precompiler that n can be of the type int . <int n>向预编译器显示n可以是int类型。 Experiment, and see what happens if you call the struct with something else.实验一下,看看如果你用别的东西调用这个结构会发生什么。

  1. Why is it necessary to put static const in front of the int value?为什么一定要把 static const 放在 int 值前面?

That's a simple question to resolve with a bit of researh The static keyword and its various uses in C++ .这是一个简单的问题,只需稍加研究即可解决static 关键字及其在 C++ 中的各种用途 Static methods can be called on the struct itself rather than on instances of the struct. Static 方法可以在结构本身而不是结构的实例上调用。

  1. Here recursion is used, so I assume that for example n = 3 the fibonacci<2> and fibonacci<1> will be called.这里使用了递归,所以我假设例如 n = 3 fibonacci<2> 和 fibonacci<1> 将被调用。 For the fibonacci<2> the fibonacci<1> and fibonacci<0> will be called.对于斐波那契<2>,将调用斐波那契<1> 和斐波那契<0>。 So for every int n (until overflow) it will apply recursion until the template specialization.因此,对于每个 int n (直到溢出),它将应用递归直到模板特化。 I don't really understand the::value part.我不太了解::value 部分。 What does happen here?这里会发生什么?

that just shows what static variable you are using from that structure.这只是显示了您从该结构中使用的 static 变量。 You are using value from fibonacci<n - 1> and etc. Similar to the way you would call a variable from an instance instance.value .您正在使用来自fibonacci<n - 1>等的value 。类似于从实例instance.value调用变量的方式。 This is tied to your question 2.这与您的问题2有关。

Is it correct to assume that this part indicates that only integer values are allowed in the struct?假设这部分表明结构中只允许 integer 值是否正确?

template<int n> 

There are different possible types of template parameters.有不同的可能类型的模板参数。 You generally have to distinguish between typed and non-type template parameters.您通常必须区分类型模板参数和非类型模板参数。 Here you have the non typed parameter case where you can specialize your base template from above for distinct integer values.在这里,您有非类型化参数案例,您可以从上面专门化您的基本模板以获得不同的 integer 值。 For the fibonacci scheme, this is done within the abort criteria of the recursion.对于斐波那契方案,这是在递归的中止标准内完成的。

Why is it necessary to put static const in front of the int value?为什么一定要把 static const 放在 int 值前面?

Shortly spoken: To have it available already within template resolution context at compile time and to not being forced to actually (OOP-)instantiate each template (which would reduce template usage here to absurdity somehow).简而言之:在编译时使其在模板解析上下文中可用,并且不被迫实际(OOP-)实例化每个模板(这会以某种方式将模板的使用减少到荒谬的程度)。

A bit more details:更多细节:

Since C++11, you are allowed to initialize a few integral types at compile time with static const.由于 C++11,您可以在编译时使用 static const 初始化一些整数类型。 Before that, this was not possible and you had to apply some tricks to get the compile time fibonacci algorithm working (enums where used for that for instance).在此之前,这是不可能的,您必须应用一些技巧来使编译时斐波那契算法正常工作(例如,使用枚举的地方)。 At least since C++17, things can be made much clearer now for many scenarios via至少从 C++17 开始,对于许多场景,现在可以通过

static constexpr int value = 1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM