首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是对编译器的“提示”(如内联)还是“绑定请求”?

是对编译器的“提示”(如内联)还是“绑定请求”?
EN

Stack Overflow用户
提问于 2014-05-21 06:37:27
回答 4查看 1.3K关注 0票数 20

constexpr是编译器的指示符,还是强制的行为?

下面是下面的例子:

代码语言:javascript
复制
template<typename T> 
std::size_t constexpr getID() { return typeid(T).hash_code(); }

hash_code是一个运行时常量,但是即使使用constexpr请求编译时计算,这个片段也会是编译。只有在使用了预期编译时间常数的返回值之后,我们才会注意到这个不能用作constexpr函数。

那么,constexpr是对编译器的“提示”(很像inline关键字)还是“绑定请求”呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-05-21 06:45:33

来自C++11 Wiki页面

如果用非常量表达式的参数调用一个constexpr函数或构造函数,则调用的行为就好像该函数不是constexpr一样,并且得到的值不是一个常量表达式。类似地,如果一个constexpr函数的返回语句中的表达式不计算为一个特定调用的常量表达式,则结果不是一个常量表达式。

因此,constexpr说明符表达了在编译时计算某些内容的可能性,并且在使用时受一些限制约束。

对于您的特定片段,在我看来,C++11约束:

正好有一个返回语句,它只包含文字值、constexpr变量和函数。

未实现,因为hash_code被定义为:

代码语言:javascript
复制
size_t hash_code() const;

在这种情况下,标准草案n3242说:

对于一个constexpr函数,如果不存在函数参数值,以致函数调用替换将产生一个常量表达式(5.19),则程序的格式不正确;不需要诊断。

我相信你的例子很适合这里。

票数 7
EN

Stack Overflow用户

发布于 2014-05-21 09:08:44

constexpr是对编译器的“提示”(如内联)还是“绑定请求”?

两者都不是。忘记它什么时候被评估。每当编译器认为有必要产生C++抽象机器的行为时(只有少数几个小例外,特别是涉及到C++的情况),都会对其进行评估。当事情被评估的时候,没有什么可说的了。

编译器可以自由地生成代码,在不产生不同行为的情况下,可以在运行时计算什么是常量表达式。它可以自由地生成代码,在编译时评估没有标记constexpr的东西,如果它有智慧的话。

如果不是关于编译时和运行时,那么constexpr是关于什么的呢?

constexpr允许将事物视为常量表达式。任何标记为constexpr的内容都必须具有以某种方式生成常量表达式的可能性。

在函数的情况下,它们可以用某些参数生成常量表达式,但不能生成其他参数。但是,只要有一些参数可以导致一个常量表达式,一个函数就可以被标记为constexpr。如果在函数调用中使用了这样一组参数,则该表达式是一个常量表达式。这是否意味着在编译时对其进行评估?请参见上面的。当编译器认为合适时,会对其进行评估。它唯一的意思是,您可以在需要常量表达式的上下文中使用它。

对于变量,它们要么是常量表达式,要么不是常数表达式。它们没有参数,所以如果constexpr总是必须用常量表达式初始化。

TL;DRconstexpr是将事物标记为在常量表达式中可用,而不是决定何时对它们进行评估。

这样一来,您的函数模板就会出现格式错误。没有一组参数可以导致常量表达式。不过,该标准不需要对此进行诊断。

票数 14
EN

Stack Overflow用户

发布于 2014-05-21 07:18:13

compile函数可用于计算编译时间常数。因此,可以这样使用它:

代码语言:javascript
复制
 constexpr int func(int a) { return a+2; }

 char x[func(10)];

如果在运行时调用func,编译器可以在可能的情况下对该表达式进行计算。但是,如果输入也是const,则这不是必须的,但通常是这样做的。

同样重要的是,要有警察建设者。这是获得非POD类constexpr对象的唯一机会。

代码语言:javascript
复制
    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;
    }   
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23775705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档