C++ “constexpr是一个”吗;提示“;(如内联)或;具有约束力的请求”;到编译器?
C++ “constexpr是一个”吗;提示“;(如内联)或;具有约束力的请求”;到编译器?,c++,c++11,constexpr,C++,C++11,Constexpr,constexpr是编译器的一个指示符,还是它规定了一种行为 目前的例子如下: template<typename T> std::size_t constexpr getID() { return typeid(T).hash_code(); } 模板 std::size_t constexpr getID(){return typeid(t).hash_code();} hash\u code是一个运行时常量,但即使使用constexpr请求编译时求值,此代码段也会被删除。
constexpr
是编译器的一个指示符,还是它规定了一种行为
目前的例子如下:
template<typename T>
std::size_t constexpr getID() { return typeid(T).hash_code(); }
模板
std::size_t constexpr getID(){return typeid(t).hash_code();}
hash\u code
是一个运行时常量,但即使使用constexpr
请求编译时求值,此代码段也会被删除。只有在返回值用于预期编译时常量的地方,我们才会注意到这一点
那么constexpr
是对编译器的“提示”(很像inline
关键字)还是“绑定请求”?来自:
如果使用以下参数调用constexpr函数或构造函数
如果不是常量表达式,则调用的行为就像函数是
不是constexpr,并且结果值不是常量表达式。
同样,如果constexpr的return语句中的表达式
函数的计算结果不是特定函数的常量表达式
调用时,结果不是一个常量表达式
因此,constexpr
说明符表示在编译时对某些内容求值的可能性,并且在使用时会受到限制
对于您的特定代码片段,我认为C++11约束: 只有一条返回语句只包含文字值, constexpr变量和函数 未满足,因为哈希_代码定义为:
size_t hash_code() const;
在这种情况下,报告说:
对于constexpr函数,如果不存在函数参数值,则
函数调用替换将产生一个常量
表达式(5.19),程序格式不正确;无需诊断
我相信您的示例适合这里。constexpr函数可用于计算编译时常量。因此,可以像这样使用它:
constexpr int func(int a) { return a+2; }
char x[func(10)];
如果在运行时调用func,则编译器可以在可能的情况下对该表达式求值。但这不是必须的,但如果输入也是常量,则通常会这样做
拥有constexpr构造函数也很重要。这是获得非POD类constexpr对象的唯一机会
class Point
{
private:
int x;
int y;
public:
constexpr Point( int _x, int _y) : x(_x), y(_y) {}
constexpr int GetX() const { return x; }
};
constexpr Point p{1,2};
int main()
{
char i[p.GetX()];
return 0;
}
您的问题的完整答案有两个方面:
#include <typeinfo>
#include <array>
template<typename T>
std::size_t constexpr getID() {
return []() {constexpr size_t id = typeid(T).hash_code(); return id;}(); }
int main() {
// both statement generate compiler errors
//std::array<int, typeid(int).hash_code()> a;
//constexpr size_t y = typeid(int).hash_code();
size_t x = getID<int>();
}
#包括
#包括
模板
std::size\u t constexpr getID(){
return[](){constexpr size_t id=typeid(t).hash_code();return id;}();}
int main(){
//这两个语句都会生成编译器错误
//std::数组a;
//constexpr size_t y=typeid(int).hash_code();
size_t x=getID();
}
constexpr
是编译器的“提示”(如内联)还是“绑定请求”
两者都不是。忘记评估它的时间。每当编译器认为有必要生成C++抽象机的行为时,就可以评估所有(有几个小例外,特别是涉及<>代码> Value)。当事情被评估时,没有太多的话要说
编译器可以自由地生成代码,在运行时计算常量表达式,如果这不会产生不同的行为。如果有smarts,它可以在编译时自由地生成代码来评估未标记的内容
如果不是关于编译时与运行时,那么constexpr
是关于什么的呢
constexpr
允许将事物视为常量表达式。任何标记为constexpr
的内容都必须能够以某种方式生成常量表达式
对于函数,它们可以生成带有某些参数的常量表达式,但不能生成其他参数的常量表达式。但只要有一组参数可以生成常量表达式,函数就可以标记为constexpr
。如果在函数调用中使用了这样一组参数,则该表达式是一个常量表达式。这是否意味着它是在编译时计算的?见上文。在编译器认为合适时对其进行评估。它的唯一含义是,您可以在需要常量表达式的上下文中使用它
对于变量,它们要么是常量表达式,要么不是常量表达式。它们没有参数,因此如果constexpr
它们总是必须用常量表达式初始化
TL;DR:constexpr
是关于将事物标记为在常量表达式中可用,而不是决定何时对它们求值
这样一来,您的函数模板似乎格式不正确。没有可能导致常量表达式的参数集。不过,该标准不需要对此进行诊断。注意,因为这是一个模板,所以在您使用一些
t
实例化它之前,没有任何函数。在这里,您可以看到此函数的实例化compiling@Mehrdad校正内联的thnx也不是提示。@rubenvb:“尽可能有效”没有意义(好,QOI)华夫饼,但是ODR规则改变(代码< >代码> >代码>的真正的GUT是强制的行为改变(至少在C++中,这是我在原来的注释中提到的)。所以基本上<代码> CONTXPRPR <代码>对语言是毫无意义的补充。@ Mehrdad:根本没有。您仍然可以使用编译时常量值调用constexpr函数,也可以在编译时对它们求值。@user2799037:问题不在于它们可以在编译时求值,而在于它们只能用于