g ++不用assert在其中编译constexpr函数 [英] g++ doesn't compile constexpr function with assert in it

查看:834
本文介绍了g ++不用assert在其中编译constexpr函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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); 
}




错误 constexpr函数体 constexpr T getClamped(const T& const T& const T&)[with T = long unsigned int]' not a return-statement / p>

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 不抱怨。

谁在这里?

Who is right here? Any way I can make g++ compile the code without using macros?

推荐答案

GCC是对的。但是,有一个相对简单的解决方法:

GCC is right. However, there is a relatively simple workaround:

#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));
}

我们滥用逗号运算符两次。

where we abuse the comma operator, twice.

第一次,因为我们想要一个 assert ,当 true 可以从 constexpr 函数中调用。第二个,所以我们可以将两个函数链接到一个 constexpr 函数中。

The first time because we want to have an assert that, when true, can be called from a constexpr function. The second, so we can chain two functions into a single constexpr function.

constexpr_assert 表达式在编译时无法验证为 true ,则 getClamped 函数不是 constexpr

As a side benefit, if the constexpr_assert expression cannot be verified to be true at compile time, then the getClamped function is not constexpr.

assert_helper 存在,因为 assert 的内容是在 NDEBUG 为真时定义的实现,因此我们无法将其嵌入表达式(它可以是一个语句,而不是一个表达式)。它还保证失败的 constexpr_assert 无法 constexpr ,即使 assert constexpr (例如,当 NDEBUG 为false)。

The assert_helper exists because the contents of assert are implementation defined when NDEBUG is true, so we cannot embed it into an expression (it could be a statement, not an expression). It also guarantees that a failed constexpr_assert fails to be constexpr even if assert is constexpr (say, when NDEBUG is false).

所有这一切的一个缺点是,你的assert不会发生问题的行,但是2调用更深。

A downside to all of this is that your assert fires not at the line where the problem occurs, but 2 calls deeper.

这篇关于g ++不用assert在其中编译constexpr函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆