为什么内联对象不是constexpr?

时间:2017-11-07 14:04:10

标签: c++ c++11 constexpr

使用this constexpr断言函数,如果对象是constexpr,则无法在构建时编译对象。

但是,对于内联对象,断言是在运行时而不是构建时触发的(参见下面的代码)。

在main函数中,第一个对象无法编译(如预期的那样) 第二个对象已编译,但执行在运行时中止(如预期的那样) 但是编译第三个对象时,编译器不应该允许它。

这意味着内联对象不是constexpr?
在这种情况下,有没有办法使内联对象constexpr?

#include <cassert>
#include <utility>

// constexpr assert. Sources:
// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/
// https://gist.github.com/oliora/928424f7675d58fadf49c70fdba70d2f

template<class Assert>
void _constexpr_assert_failed(Assert&& a) noexcept
{
    std::forward<Assert>(a)();
}

// When evaluated at compile time emits a compilation error if condition is not true.
// Invokes the standard assert at run time.
#define FOO_ASSERT(cond) \
        ((void)((cond) ? 0 : (_constexpr_assert_failed([](){ assert(! bool(#cond)); }), 0)))

template<typename Type>
constexpr const Type& assertRange(const Type& value, const Type& minimum, const Type& maximum) noexcept
{
    return FOO_ASSERT(value >= minimum && value <= maximum),
           value;
}

struct Color
{
    float r;
    float g;
    float b;

    constexpr Color(float r, float g, float b) noexcept :
        r(assertRange(r, 0.0f, 1.0f)),
        g(assertRange(g, 0.0f, 1.0f)),
        b(assertRange(b, 0.0f, 1.0f))
    {
    }
};

Color foo(const Color& color)
{
    return Color(color.r * 0.5f, color.g * 0.5f, color.b * 0.5f);
}

int main()
{
    // Build time error:
    // constexpr Color constexprBadColor(10, 0, 0);

    // Run time error:
    // Color runtimeBadColor(10, 0, 0);

    // Run time error?
    foo(Color(10, 0, 0));

    return 0;
}

0 个答案:

没有答案