Why non type template parameters that are references need const?

huangapple go评论126阅读模式
英文:

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.

英文:

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&lt;const /* &lt;-- required */ Country&amp; country&gt;
struct S{
    void print() {
        fmt::print(&quot;{}\n&quot;, country.name);
    }
};

static constexpr Country sg{.name=&quot;Singapore&quot;};
int main() {
    
    S&lt;sg&gt; 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

得分: 4

非类型模板参数,如果是引用,可以是非const的。你的错误原因是尝试将一个const对象绑定到非const引用上。如果移除两个const,错误就消失了:

#include <string>
#include <iostream>

struct Country {
    std::string name;
};

template<Country& country>  // 不需要const
struct S {
    void print() {
        country = Country{"foo"};
        std::cout << country.name;
    }
};

static Country sg{"sg"};    // 不需要const

int main() {
    S<sg> sg_printer;  
    sg_printer.print();    
}

演示链接

英文:

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 &lt;string&gt;
#include &lt;iostream&gt;

struct Country {
    std::string name;
};

template&lt;Country&amp; country&gt;  // no const necessary
struct S{
    void print() {
        country = Country{&quot;foo&quot;};
        std::cout &lt;&lt; country.name;
    }
};

static Country sg{&quot;sg&quot;};    // no const

int main() {
    S&lt;sg&gt; sg_printer;  
    sg_printer.print();    
}

Live Demo

huangapple
  • 本文由 发表于 2023年4月13日 16:22:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76003231.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定