constexpr是编译器的指示符,还是强制的行为?
下面是下面的例子:
template<typename T>
std::size_t constexpr getID() { return typeid(T).hash_code(); }hash_code是一个运行时常量,但是即使使用constexpr请求编译时计算,这个片段也会是编译。只有在使用了预期编译时间常数的返回值之后,我们才会注意到这个不能用作constexpr函数。。
那么,constexpr是对编译器的“提示”(很像inline关键字)还是“绑定请求”呢?
发布于 2014-05-21 06:45:33
来自C++11 Wiki页面
如果用非常量表达式的参数调用一个constexpr函数或构造函数,则调用的行为就好像该函数不是constexpr一样,并且得到的值不是一个常量表达式。类似地,如果一个constexpr函数的返回语句中的表达式不计算为一个特定调用的常量表达式,则结果不是一个常量表达式。
因此,constexpr说明符表达了在编译时计算某些内容的可能性,并且在使用时受一些限制约束。
对于您的特定片段,在我看来,C++11约束:
正好有一个返回语句,它只包含文字值、constexpr变量和函数。
未实现,因为hash_code被定义为:
size_t hash_code() const;在这种情况下,标准草案n3242说:
对于一个constexpr函数,如果不存在函数参数值,以致函数调用替换将产生一个常量表达式(5.19),则程序的格式不正确;不需要诊断。
我相信你的例子很适合这里。
发布于 2014-05-21 09:08:44
constexpr是对编译器的“提示”(如内联)还是“绑定请求”?
两者都不是。忘记它什么时候被评估。每当编译器认为有必要产生C++抽象机器的行为时(只有少数几个小例外,特别是涉及到C++的情况),都会对其进行评估。当事情被评估的时候,没有什么可说的了。
编译器可以自由地生成代码,在不产生不同行为的情况下,可以在运行时计算什么是常量表达式。它可以自由地生成代码,在编译时评估没有标记constexpr的东西,如果它有智慧的话。
如果不是关于编译时和运行时,那么
constexpr是关于什么的呢?
constexpr允许将事物视为常量表达式。任何标记为constexpr的内容都必须具有以某种方式生成常量表达式的可能性。
在函数的情况下,它们可以用某些参数生成常量表达式,但不能生成其他参数。但是,只要有一些参数可以导致一个常量表达式,一个函数就可以被标记为constexpr。如果在函数调用中使用了这样一组参数,则该表达式是一个常量表达式。这是否意味着在编译时对其进行评估?请参见上面的。当编译器认为合适时,会对其进行评估。它唯一的意思是,您可以在需要常量表达式的上下文中使用它。
对于变量,它们要么是常量表达式,要么不是常数表达式。它们没有参数,所以如果constexpr总是必须用常量表达式初始化。
TL;DR:constexpr是将事物标记为在常量表达式中可用,而不是决定何时对它们进行评估。
这样一来,您的函数模板就会出现格式错误。没有一组参数可以导致常量表达式。不过,该标准不需要对此进行诊断。
发布于 2014-05-21 07:18:13
compile函数可用于计算编译时间常数。因此,可以这样使用它:
constexpr int func(int a) { return a+2; }
char x[func(10)];如果在运行时调用func,编译器可以在可能的情况下对该表达式进行计算。但是,如果输入也是const,则这不是必须的,但通常是这样做的。
同样重要的是,要有警察建设者。这是获得非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;
} https://stackoverflow.com/questions/23775705
复制相似问题