为什么要在构造函数上使用constexpr?

12

我理解 constexpr 可以让你在编译时将对象用作常量,但是这种情况的实际应用有哪些呢?我想更好地理解这个关键词,但我找不到一个很好的例子来说明为什么需要在构造函数上使用它。

下面的两个示例都能正常工作,那么为什么要在构造函数上放置 constexpr 呢?

将 constexpr 放在构造函数中的示例:

#include <iostream>
using namespace std;

class Rect
{
    public:
        constexpr Rect(int width, int height)
            : mWidth(width), mHeight(height) {}
        constexpr int getArea() const { return mWidth * mHeight; }
    private:
        int mWidth, mHeight;
};

int main(int argc, char* argv[])
{
    constexpr Rect r(8, 2);

    cout << r.getArea() << endl;   //16

    int myArray[r.getArea()];    // OK


    return 0;
}

没有在构造函数上使用constexpr:

#include <iostream>
using namespace std;

class Rect
{
    public:
        Rect(int width, int height)
            : mWidth(width), mHeight(height) {}
        constexpr int getArea() const { return mWidth * mHeight; }
    private:
        int mWidth, mHeight;
};

int main(int argc, char* argv[])
{
    Rect r(8, 2);

    cout << r.getArea() << endl;   //16

    int myArray[r.getArea()];    // OK


    return 0;
}

1
第二个对我来说无法编译:http://coliru.stacked-crooked.com/a/a84bbdd8fb82bb49 - Brian Bi
但是getArea()的两个示例中都使用了constexpr - user5390668
3
如果一个函数被标记为constexpr,那么它只有在其参数(包括隐含的*this)也是常量表达式时才返回常量表达式。 - M.M
@Brian clang接受这段代码。我发起了一个新问题,寻求帮助。 - M.M
1个回答

13
在你的第二个示例中,int myArray[r.getArea()];在标准C++中是不被允许的,因为r.getArea()不是一个常量表达式。(如果你的编译器接受它,那么你就要依赖于编译器的扩展,并且如果你在符合模式下调用编译器,则应生成警告)。
如果你将数组改为以下形式,则差异可能更加明显:
std::array<int, r.getArea()> myArray;

在非constexpr版本中,编译器不太可能接受它。


1
那并没有回答我的问题,但你的意思是只有在需要在编译时将对象用作文字时才会在构造函数上使用constexpr - user5390668
1
@EavenSheets 你问道:“下面的两个例子都可以工作,那么为什么要将constexpr放在构造函数上呢?”我通过展示你的第二个例子实际上是无法工作的来回答这个问题,并且将constexpr放在构造函数上可以使其工作。“为什么要在构造函数上使用constexpr?”答案是:“如果你想让该类的对象能够用于生成常量表达式”。 - M.M
4
这并没有回答这个问题。 - Lightness Races in Orbit
2
@LightnessRacesinOrbit 我认为是这样的。如果你不同意,也许你可以发表自己的答案。 - M.M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接