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

问题描述 投票:2回答:2

我有关于constexpr的以下问题,我有点明白,人们不能宣称std::shared_ptr<T>const,但为什么第一个static_assert()有效?

另外,第二个static_assert()如何运作?我想有一个std::variants数组,它们是consts,并希望有编译时类型检查来强制执行该类型;然而,似乎如果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 
}
c++ c++17 constexpr variant static-assert
2个回答
3
投票

我有点理解,不能将shared_ptr声明为const,但为什么第一个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 :: variants数组,它们是consts,并希望进行编译时类型检查以强制执行该类型;但是,似乎如果shared_ptr是变体类型之一,则它不能被声明为constexpr;但是如果我将容器声明为std :: tuple,即使没有constexpr注释,(I)似乎也可以工作;

不明白你的意思。

如果你的意思是“第二次static_assert工作”

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

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


0
投票

// 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字段。

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

© www.soinside.com 2019 - 2024. All rights reserved.