我有关于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
}
我有点理解,不能将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);
这是因为var1
是constexpr
和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
字段。
接下来,std::get
上的variant
也标记为constexpr
,并且由于变体被构造为constexpr
,我们可以在编译时获得值3
。