问题描述
可以根据C ++ 11表达式是否是C ++中的常量表达式(即 constexpr
)生成编译时布尔值11?
Is it possible to produce a compile-time boolean value based on whether or not a C++11 expression is a constant expression (i.e. constexpr
) in C++11? A few questions on SO relate to this, but I don't see a straight answer anywhere.
推荐答案
我曾经写过这个问题编辑:见下面的限制和解释)。从:
I once wrote it ( see below for limitations and explanations). From http://stackoverflow.com/a/10287598/34509 :
template<typename T>
constexpr typename remove_reference<T>::type makeprval(T && t) {
return t;
}
#define isprvalconstexpr(e) noexcept(makeprval(e))
但是有很多种常量表达式。上述答案检测prvalue常数表达式。
However there are many kinds of constant expressions. The above answer detects prvalue constant expressions.
noexcept(e)
表达式给出 false
iff e
The noexcept(e)
expression gives false
iff e
contains
- 对没有非抛出异常规范的函数的潜在求值调用,除非调用是常量表达式, li>
- 潜在评估的
throw
表达式, - 潜在评估的可抛弃形式
dynamic_cast
或typeid
。
- a potentially evaluated call to a function that does not have a non-throwing exception-specification unless the call is a constant expression,
- a potentially evaluated
throw
expression, - a potentially evaluated throwable form of
dynamic_cast
ortypeid
.
函数模板 makeprval
未声明为 noexcept
,因此调用需要是第一个项目符号的常量表达式,而不是适用,这是我们滥用。我们需要其他子弹不适用,但是很感谢, throw
和throwable dynamic_cast
或 typeid
不允许在常量表达式aswell中,所以这是罚款。
Note that the function template makeprval
is not declared noexcept
, so the call needs to be a constant expression for the first bullet not to apply, and this is what we abuse. We need the other bullets to not apply aswell, but thanksfully, both a throw
and a throwable dynamic_cast
or typeid
aren't allowed in constant expressions aswell, so this is fine.
不幸的是,有一个子菜单限制,这可能对您或不重要。 潜在评估的概念比常数表达式适用的限制更保守。所以上面的 noexcept
可能给出假的否定。它会报告一些表达式不是prvalue常量表达式,即使它们是。示例:
Unfortunately there is a suble limitation, which may or may not matter for you. The notion of "potentially evaluated" is much more conservative than the limits of what constant expressions apply. So the above noexcept
may give false negatives. It will report that some expressions aren't prvalue constant expressions, even though they are. Example:
constexpr int a = (0 ? throw "fooled!" : 42);
constexpr bool atest = isprvalconstexpr((0 ? throw "fooled!" : 42));
在上面的 atest
虽然 a
的初始化成功。这是因为作为常数表达式,足以使邪恶非常数子表达式从不评估,即使这些邪恶子表达式可能被正式评估。
In the above atest
is false, even though the initialization of a
succeeded. That is because for being a constant expression, it suffices that the "evil" non-constant sub-expressions are "never evaluated", even though those evil sub-expressions are potentially-evaluated, formally.
这篇关于is_constexpr可能在C ++ 11吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!