Why non type template parameters that are references need const?

118 Views Asked by At

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.

1

There are 1 best solutions below

1
463035818_is_not_an_ai On BEST ANSWER

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