在static_assert命名空间中使用constexpr会产生错误

时间:2017-12-06 16:22:34

标签: c++ c++11

我在头文件中声明了以下内容。

namespace G1
{
    inline namespace V1
    {
        constexpr float getV();
    }
}

在CPP文件中,我已将getV函数定义为

constexpr float G1::V1::getV()
{
    return 0.1f;
}

主要是我使用static_assert来比较显示的版本。

int main()
{
    static_assert( G1::getV() == 1.0f, "Error"); // Please Ignore the way I am comparing the floats
    return 0;
}

但是当我编译代码时,我得到expression did not evaluate to a constant

我在这里做错了吗?我正在使用VS2015。 提前致谢

2 个答案:

答案 0 :(得分:3)

实际上,C ++编译模型是2阶段。首先编译,然后链接。

constexpr仅适用于编译阶段。没有要求编译器可以将constexpr函数体折叠到调用网站中,这样做需要链接时constexpr评估。

因此,当您未能为constexpr函数提供正文时,任何无法看到该正文的人都不会在编译时对其进行评估,而是等到运行时。

constexpr并不意味着"将在编译时运行",而是#34;可以在某些情况下在编译时运行"。

答案 1 :(得分:2)

如果希望编译器编译main以了解值getV在编译时返回 ,则必须在头文件中实现该函数。 由于您使用static_assert,因此在编译时需要定义。

只有包含getV的.cpp文件的编译器才能知道它返回的内容。这通常是一个不同的编译器调用。

根据链接时间,检查static_assert

为时已晚

错误消息:expression did not evaluate to a constant是由编译器不知道实现引起的。在"运行时"它会在这里插入一个调用,稍后由链接器修复并在运行时执行。但是,运行时调用永远不是编译时常量。