我对constexpr
概念感到困惑,因为我在编译时会对constexpr
进行评估,因此它对于性能优化与普通const
非常有用。
constexpr int i = 0;
constexpr int& ri = i;
上面的代码返回错误"类型' int&'的引用无效初始化从表达类型' const int'",为什么?
此外,下一个代码有错误:
constexpr int i = 0;
constexpr int* ri = &i;
如果我将constexpr
关键字替换为const
,则上述所有操作都正常。
答案 0 :(得分:13)
constexpr int i = 0;
constexpr int * ri = &i;
第二行是个问题,因为指针不指向const
对象。指针本身是const
。
使用
constexpr int i = 0;
constexpr int const * ri = &i;
解决了这个问题。但是,如果变量是在函数范围内定义的,那仍然是个问题。
constexpr int i = 0;
constexpr int const* ri = &i;
int main() {}
是一个有效的程序。
void foo()
{
constexpr int i = 0;
constexpr int const* ri = &i;
}
int main() {}
不是有效的程序。
以下是关于地址常量表达式的C ++ 11标准所说的内容:
5.19常量表达式
3 .. 地址常量表达式是指针类型的prvalue核心常量表达式,其计算为具有静态存储持续时间的对象的地址,函数的地址,或空指针值或prvalue类型
std::nullptr_t
的核心常量表达式。
答案 1 :(得分:6)
RE
“如果我用const替换constexpr字以上都正常工作。”
const int*
本质上意味着(const int)*
,但您不能以这种方式使用括号。 constexpr int*
表示constepxr (int*)
(同上注释)。
这是因为constexpr
不是该类型的一部分,您不能将类型命名为constexpr int
,例如,const
是该类型的一部分。
而不是
constexpr int i = 0;
constexpr int& ri = i;
尝试声明constexpr
对非const
的引用,只需编写
constexpr int i = 0;
constexpr int const& ri = i;
您可以向后阅读,因为ri
是const
int
的引用,constexpr
(在编译时评估)。
<强>附录强>:
出现C ++ 14要求本地非static
constexpr
个对象具有自动存储持续时间,以 as-if 为模优化规则。
为了满足这一要求,即为了使代码在编译器之间可移植,如果上述声明在函数中本地出现,则添加static
以确保对象所引用的对象的静态存储持续时间:
void oops()
{
static constexpr int i = 0; // Necessary with some compilers.
constexpr int const& ri = i;
}
否则它可能无法用例如g ++,它可能是 C ++ 14和C ++ 11标准所需要的,省略constexpr
上的适当约束。
注意:
¹请参阅discussion of R. Sahu's answer。
功能
答案 2 :(得分:3)
正如您所说,function closeDropDown() {
$scope.opened = false;
}
function handleClickEvent(event) {
/* When the clicked element is not a child of the element and
the dropdown is openend, close the dropdown. */
if ($element.find(event.target).length === 0 && $scope.opened) {
closeDropDown();
/* Trigger new digest cycle */
$scope.$apply();
}
};
function setListeners() {
/* Bind click event to the document, close the dropDown if clicked
elsewhere on the page. */
var clickHandler = handleClickEvent;
$document.bind('click', clickHandler);
/* Remove the used event handlers when destroying the object */
$scope.$on('$destroy', function () {
$document.unbind('click', clickHandler);
});
}
在编译时进行评估。因此,编译时必须可以评估该值。
例如:
constexpr
对于第一行,0在编译时是可评估的,其值为0.
但对于第二行,编译器需要constexpr int i = 0;
constexpr int& ri = i;
的地址来执行赋值,这是在运行时确定的。所以这一行会失败。
答案 3 :(得分:1)
这是我的2美分:
constexpr
功能定义了在编译期间发生的计算。合理的问题:
合理的答案:
由于该标准允许在constexpr
代码中使用非常有限的一组功能。人们可能会争论为什么这个集合而不是更多?那么,以后的标准可能会发展并允许更多。