使用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;
}