英文:
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_bzerofrom within aconstexprdestructor? Since theifin 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 
constexprconstructed? 
英文:
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_bzerofrom within aconstexprdestructor? Since theifin 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 
constexprconstructed? 
答案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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论