Search code examples
c++c++23non-type-template-parameter

Why non type template parameters that are references need const?


I am familiar with how const behaves for "runtime" code and it makes perfect sense, but since "everything done during compilation is const" (obviously this is not my interpretation, not standard wording) I wonder why C++ cares about if the reference is const or not.

In particular this example does not compile when const is removed:

struct Country {
    std::string_view name;
};

template<const /* <-- required */ Country& country>
struct S{
    void print() {
        fmt::print("{}\n", country.name);
    }
};

static constexpr Country sg{.name="Singapore"};
int main() {
    
    S<sg> sg_printer;  
    sg_printer.print();    
}



error for gcc is something like:

error: binding reference of type 'Country&' to 'const Country' discards qualifiers

My only guess that nobody thought about this or that this was done to be same as for "normal" code so that it is consistent.


Solution

  • Non type template arguments that are references can be non-const.

    The reason for your error is that you are trying to bind a const object to a non-const reference. The error is gone if both const are removed:

    #include <string>
    #include <iostream>
    
    struct Country {
        std::string name;
    };
    
    template<Country& country>  // no const necessary
    struct S{
        void print() {
            country = Country{"foo"};
            std::cout << country.name;
        }
    };
    
    static Country sg{"sg"};    // no const
    
    int main() {
        S<sg> sg_printer;  
        sg_printer.print();    
    }
    

    Live Demo