template<typename T> constexpr inline
T getClamped(const T& mValue, const T& mMin, const T& mMax)
{
assert(mMin < mMax); // remove this line to successfully compile
return mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue);
}
error: body of constexpr function 'constexpr T getClamped(const T&, const T&, const T&) [with T = long unsigned int]' not a return-statement
使用 g++ 4.8.1
。 clang++ 3.4
没有提示。
谁在这里?有什么方法可以让 g++
在不使用宏的情况下编译代码?
最佳答案
GCC 是对的。但是,有一个相对简单的解决方法:
#include "assert.h"
inline void assert_helper( bool test ) {
assert(test);
}
inline constexpr bool constexpr_assert( bool test ) {
return test?true:(assert_helper(test),false);
}
template<typename T> constexpr
inline T getClamped(const T& mValue, const T& mMin, const T& mMax)
{
return constexpr_assert(mMin < mMax), (mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue));
}
我们两次滥用逗号运算符。
第一次是因为我们想要一个 assert
,当 true
时,可以从 constexpr
函数调用。第二,我们可以将两个函数链接到一个 constexpr
函数中。
附带的好处是,如果 constexpr_assert
表达式在编译时无法验证为 true
,则 getClamped
函数不是 constexpr
。
assert_helper
的存在是因为 assert
的内容是在 NDEBUG
为真时定义的实现,所以我们不能将它嵌入到表达式中(它可以是语句,而不是表达式)。它还保证失败的 constexpr_assert
无法成为 constexpr
,即使 assert
是 constexpr
(例如,当 NDEBUG
为假)。
所有这一切的缺点是您的断言不是在出现问题的行触发,而是在更深的 2 个调用处触发。
关于c++ - g++ 不编译带有断言的 constexpr 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18648069/