Nontype template parameter

前端 未结 3 2123
清歌不尽
清歌不尽 2021-01-06 18:21

I\'m having trouble with nontype(int variable) template parameter.
Why can\'t I pass a constant int variable to a function and let the function instantiate the template?

相关标签:
3条回答
  • 2021-01-06 19:03

    Because j should be known at compile time. In your example it is not.

    0 讨论(0)
  • Basically, C++ has two kinds of constants:

    const int a = 5;
    MyTemplate<a> foo; // OK
    
    const int b = rand();
    MyTemplate<b> foo; // Not OK.
    

    The first example is a compile-time constant. In C++ standard speak, it's an Integral Constant Expression (ICE). The second example is a run-time constant. It has the same C++ type (const int) but it's not an ICE.

    Your function void run(const int j) is a run-time constant. You could even pass in user input. Therefore it's not a valid template argument.

    The reason for the rule is that the compiler must generate code based on the template argument value. It can't do so if it doesn't have a compile-time constant.

    0 讨论(0)
  • 2021-01-06 19:16

    Because non-type template parameters require values at compile-time. Remember that templates are a compile-time mechanism; templates do not exist in the final executable. Also remember that functions and the passing of arguments to functions are runtime mechanisms. The value of the j parameter in run() will not be known until the program actually runs and invokes the run() function, well past after the compilation stage.

    void run(const int j)
    {
        // The compiler can't know what j is until the program actually runs!
        MyTemplate<j> b;
    }
    
    const int i = 3;
    run(i);
    

    That's why the compiler complains says "'j' cannot appear in constant-expression".

    On the other hand, this is fine because the value of i is known at compile-time.

    const int i = 3;
    // The compiler knows i has the value 3 at this point,
    // so we can actually compile this.
    MyTemplate<i> a;
    

    You can pass compile-time values to run-time constructs, but not the other way around.

    However, you can have your run() function accept a non-type template parameter the same way your MyTemplate template class accepts a non-type template parameter:

    template<int j>
    void run()
    {
        MyTemplate<j> b;
    }
    
    const int i = 3;
    run<i>();
    
    0 讨论(0)
提交回复
热议问题