英文:
constexpr instances of class that usually have non-constexpr behavior in the destructor, in C++20
问题
I would like to be able to create constexpr
values for a type that usually has a non-trivial destructor. Unfortunately, I'm using C++20, so don't have if consteval
. Here is a minimal working example that is accepted by gcc 12.2.1 and clang++ 15.0.7, but I'm not sure if it's legal:
#include <type_traits>
#include <string.h>
struct secret {
int value_;
constexpr secret(int value) : value_(value) {}
constexpr ~secret() {
if (!std::is_constant_evaluated())
explicit_bzero(&value_, sizeof(value_));
}
};
constexpr secret my_secret = 5;
secret my_destroyed_secret = 6;
My questions are:
- Is it legal to call a function like
explicit_bzero
from within aconstexpr
destructor? Since theif
in the destructor is notconstexpr
, it seems like it should be illegal. - If it is legal, then why?
- If it is not legal, then is there any other way to accomplish what I want--basically clobber any destroyed value that wasn't
constexpr
constructed?
英文:
I would like to be able to create constexpr
values for a type that usually has a non-trivial destructor. Unfortunately, I'm using C++20, so don't have if consteval
. Here is a minimal working example that is accepted by gcc 12.2.1 and clang++ 15.0.7, but I'm not sure if it's legal:
#include <type_traits>
#include <string.h>
struct secret {
int value_;
constexpr secret(int value) : value_(value) {}
constexpr ~secret() {
if (!std::is_constant_evaluated())
explicit_bzero(&value_, sizeof(value_));
}
};
constexpr secret my_secret = 5;
secret my_destroyed_secret = 6;
My questions are:
- Is it legal to call a function like
explicit_bzero
from within aconstexpr
destructor? Since theif
in the destructor is notconstexpr
, it seems like it should be illegal. - If it is legal, then why?
- If it is not legal, then is there any other way to accomplish why I want--basically clobber any destroyed value that wasn't
constexpr
constructed?
答案1
得分: 3
是的,它是合法的。在析构函数中的条件语句不是constexpr
时,使用std::is_constant_evaluated
是唯一正确的方式。
这是为了告诉您std::is_constant_evaluated()
的评估(以及包含它的表达式)是否作为常量表达式(即在编译时评估的表达式)的一部分进行评估。如果您在if constexpr
的条件中调用它,它将始终被评估为常量表达式,且只能是true
,因为if constexpr
的条件要求本身是常量表达式,无论整个if
语句是否作为另一个常量表达式的一部分进行评估。
这似乎让人感到困惑的原因之一是,C++23引入了if consteval
以替代std::is_constant_evaluated
。请参阅提出C++23中的if consteval
的论文。
英文:
> Is this code legal? Since the if in the destructor is not constexpr, it seems like it should be illegal.
> If it is legal, then why?
Yes, it is. Using std::is_constant_evaluated
without constexpr
in an if
is the only correct way to use it.
It is supposed to tell you whether the evaluation of std::is_constant_evaluated()
(and the expression containing it) is part of evaluation as a constant expression (i.e. compile-time evaluated expression) or not. If you call it inside a condition of a if constexpr
then it is always evaluated as constant expression and can only ever be true
, because the condition of if constexpr
is required to be in itself a constant expression, regardless of whether or not the whole if
statement is evaluated as part of another constant expression.
That this seems to confuse people is one of the reasons that if consteval
was introduced in C++23 to replace std::is_constant_evaluated
. See the paper which proposed if consteval
for C++23.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论