C ++为什么这个static_assert有效:

c++ why this static_assert works:

本文关键字:assert 有效 static 为什么      更新时间:2023-10-16

我对constexpr有以下问题,我有点理解不能将std::shared_ptr<T>声明为const,但是为什么第一个static_assert()有效?

另外,第二个static_assert()是如何工作的?我想要一个std::variants数组,它们是常量,并希望进行编译时类型检查来强制执行该类型;但是,似乎如果std::shared_ptr是变体类型之一,则不能将其声明为constexpr;但是如果我将容器声明为std::tuple,即使没有constexpr注释,(I) 似乎也可以工作;

typedef std::shared_ptr<int> intp;
const auto defaults = std::make_tuple(std::make_pair(1, true),
std::make_pair(2, 3),
std::make_pair(3, intp(nullptr)));

typedef std::variant<int, bool> MyVar;
constexpr MyVar var1 = 3;
// constexpr intp x = nullptr; (I)
//typedef std::variant<int, bool, intp> MyVar2; This doesn't work
//constexpr MyVar2 var2 = 3;
int main()
{
// Q1): Why the following works, but (I) does not.
static_assert(std::is_same<decltype(std::get<2>(defaults).second), intp>::value);
// Q2): Why this works: is there a better way to say something like
//      static_assert(actual_type(var1) == int);
static_assert(std::get<int>(var1) == 3);
//static_assert(x == nullptr);  This does not work 
}

我有点理解不能将shared_ptr声明为常量,但是为什么第一个static_assert有效?

因为

static_assert(std::is_same<decltype(std::get<2>(defaults).second), intp>::value);

不创建编译时stared_ptr;只检查std::get<2>(defaults).second的类型是否为intp

如果值仅在运行时可用,则此信息在编译时也是已知的。

另外,第二个static_assert是如何工作的?我想要一个 std::variant 数组,它们是常量,并希望进行编译时类型检查来强制执行该类型;但是,似乎如果shared_ptr是变体类型之一,则不能将其声明为constexpr;但是如果我将容器声明为 std::tuple,即使没有 constexpr 注释,(I) 似乎也可以工作;

不知道你的意思。

如果对于"第二static_assert工作",你的意思是

static_assert(std::get<int>(var1) == 3);

这是因为var1constexpr的,而std::get()(对于std::variant)是constexpr;所以std::get<int>(var1)它是一个可以在编译时使用的值,编译时,在一个static_assert()

//Q1):为什么以下有效,但(I)无效。
static_assert(std::is_same<decltype(std::get<2>(defaults).second), intp>::value);

神奇之处在于:C++某些表达式被认为是未计算的decltype(...)就是其中之一(请参阅 [dcl.type.simple])

decltype(...)不被评估意味着什么?

在这方面,共同的宗旨是 编写表达式只是为了引用其类型。

把它想象成一个花哨的typedef.在这个背景下,没有什么是可以真正创造的。你可以用它做一些有趣的事情,比如使用不完整的类型。


原因

typedef std::shared_ptr<int> intp;
constexpr intp x = nullptr; 

不起作用现在应该变得很明显:这个表达式被计算,并且由于我们知道我们无法创建constexpr shared_ptr,编译失败。


Q2):为什么会这样:有没有更好的方法来表达// static_assert(actual_type(var1) == int);

static_assert(std::get<int>(var1) == 3);

这是因为std::variant具有constexpr构造函数,并且您使用编译时整数值3构造它,该值构造变体的int字段。

接下来,variant上的std::get也被标记为constexpr,并且由于变量被构造为constexpr,我们可以在编译时3获得值。