Search code examples
c++templatesgloballocalnon-type

Why template nontype parameter pointer and reference arguments needs to be global


Why arguments which are passed as nontype arguments should be global and not local? Isn't both created and allocated memory during compile time only?

In this case p is a const pointer, so it cannot point to any other variable then also its giving error.Why?

template<int* ptr>
class A{};

int x;
int *const p = &x;

int main() {
    x = 9;
    A<&x> ob;
    A<p> ob2;//giving error
    cin.get();
}

Also why only integral type is allowed as nontype parameters, not char or float?


Solution

  • Concerning the first question, I am not a compiler expert, but I can guess it makes the compiler's life easier, and perhaps it is a limitation that comes from older versions of C++, where constexpr was not available.

    Nevertheless, paragraph 14.3.2/1 of the C++11 Standard is quite clear as to what is allowed and what is not:

    A template-argument for a non-type, non-template template-parameter shall be one of:

    — for a non-type template-parameter of integral or enumeration type, a converted constant expression (5.19) of the type of the template-parameter; or

    — the name of a non-type template-parameter; or

    a constant expression (5.19) that designates the address of an object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as & id-expression, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference; or

    — a constant expression that evaluates to a null pointer value (4.10); or

    — a constant expression that evaluates to a null member pointer value (4.11); or

    — a pointer to member expressed as described in 5.3.1; or

    — an address constant expression of type std::nullptr_t.

    Concerning your second question, instead, a char is allowed. For instance, the following is a legal program:

    template<char c>
    struct X
    {
        // ...
    };
    
    int main()
    {
        X<'c'> x;
    }
    

    Concerning the reasons why floating point types are not allowed, you can find some information in this Q&A on StackOverflow.