2015-03-02 63 views
4

这更多的是一个哲学问题而不是实用的代码片段,但也许C++大师可以启发我(并且,如果已经被问到,请道歉)。constexpr的用途

我一直在阅读Meyers的“Effective Modern C++”一书中的第15项,以及此线程:implicit constexpr?(加上合理数量的谷歌搜索)。该项目结束使用constexpr表达式,即它定义的功能可以返回给定编译时间输入的编译时间值。另外,我提到的StackOverflow线程表明,一些编译器完全能够自己弄清楚编译时哪些函数调用结果是已知的。

因此,问题:为什么constexpr被添加到标准,而编译器应该派生并允许静态/编译时值定义?

我意识到它使各种编译(例如std::array<T, constexpr>)定义不太可预测,但另一方面,根据迈尔斯的书,constexpr是接口的一部分,...,如果你删除它,你可能会导致任意大量的客户端代码停止编译。 因此,不仅要明确要求人们记住添加它,还要向界面添加永久性语义。

澄清:这个问题不是关于为什么应该使用constexpr。我明白,有能力以编程方式派生编译时间值是非常有用的,并且在很多情况下我自己使用它。这是一个问题,为什么它在编译器可能自行推断const-time行为的情况下是强制性的。

说明没有。 2:这是一段代码片断,显示编译器不会自动推断出这种情况,在这种情况下,我使用了g ++。

#include <array> 

size_t test() 
    { 
    return 42; 
    } 

int main() 
    { 
    auto i = test(); 
    std::array<int, i> arrayTst; 
    arrayTst[1] = 20; 
    return arrayTst[1]; 
    } 

std::array声明编译失败,因为还没有定义test()constexpr,这当然是按照标准。如果标准不同,没有任何东西可以阻止gcc独立判断test()总是返回一个常量表达式。

这个问题并没有问“标准定义什么”,而是“为什么标准是它的样子”?

+0

可能有帮助:http://www.stroustrup.com/C++11FAQ.html#constexpr。 – 2015-03-02 23:20:08

+0

如果你的代码从简单易懂的参数中自动计算出来的话,那么魔法值是不好的,如果你的代码自动地从容易理解的参数中计算出来,那么这是一个很大的胜利。例如,我编写了一些代码,以便在编译时使用constexpr在编译时计算crc32,并且我认为对可以清楚地遵循的constexpr函数调用的可读性要高得多,而不是计算谁知道如何的魔法值。你还可以在编译时得到*保证*,这实际上在静态全局初始化不运行的情况下实际上挽救了我的生命。 – tux3 2015-03-02 23:21:08

+0

@ tux3:当然,但没有理由不能使用普通的(非'constexpr'函数)来做同样的事情。 – 2015-03-02 23:22:29

回答

5

constexpr之前,编译器有时可以找出编译时间常量并使用它。但是,程序员永远无法知道什么时候会发生。

之后,程序员立即被告知表达式是否不是编译时间常量,并且他或她意识到需要修复它。

+0

感谢您的快速回答。假设性地说,为什么'constexpr'不可选?也就是说,如果我觉得这样的倾向,我可以添加关键字得到通知,如果表达式不是恒定的(如你所述),但仍获得编译时评估的好处,如果我忽略它(包括模板ARGS等) – RomanK 2015-03-02 23:24:15

+0

@RomanK :你有证据证明你没有得到吗? – 2015-03-03 01:17:40

+0

是的,我在这个问题上增加了一个例子。如果编译器做到了,那将违背标准。 – RomanK 2015-03-03 06:43:01