首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Constexpr解密型

Constexpr解密型
EN

Stack Overflow用户
提问于 2016-02-08 18:22:00
回答 1查看 1.5K关注 0票数 5

最近我在这里问了一个问题(Detecting instance method constexpr with SFINAE),在这里我试图在编译时做一些星座检测。最后,我发现可以利用noexcept来实现这一点:任何常量表达式都是noexcept。因此,我组装了以下机器:

代码语言:javascript
运行
复制
template <class T>
constexpr int maybe_noexcept(T && t) { return 0; }
...
constexpr bool b = noexcept(maybe_noexcept(int{}));

这是可行的,b也是正确的,因为零初始化int是一个常量表达式。如果我将int更改为其他适当的类型,那么它在应该时也会正确地产生零。

接下来,我想检查一些东西是否是constexpr可移动的。所以我做了这个:

代码语言:javascript
运行
复制
constexpr bool b = noexcept(maybe_noexcept(int(int{})));

这同样适用于int或用户定义的类型。但是,这会检查该类型是否同时具有一个默认构造函数和一个constexpr移动构造函数。因此,为了解决这一问题,我试图将其改为解密:

代码语言:javascript
运行
复制
constexpr bool b = noexcept(maybe_noexcept(int(declval<int>())));

这导致b在gcc 5.3.0中是假的(因为clang不能正确地生成常量表达式noexcept,因此不能使用clang )。没有问题,我说,必须是因为declval是(有趣地)没有标记constexpr。所以我写了我自己的天真版本:

代码语言:javascript
运行
复制
template <class T>
constexpr T&& constexpr_declval() noexcept;

是的,与标准库相比,这是幼稚的,因为它会被无效或其他东西所窒息,但现在还可以。所以我再试一次:

代码语言:javascript
运行
复制
constexpr bool b = noexcept(maybe_noexcept(int(constexpr_declval<int>())));

这仍然不起作用,b总是错误的。为什么这不被认为是一个不变的表达?这是一个编译器错误,还是我不了解constexpr的基本知识?在constexpr和未评估的上下文之间似乎存在一些奇怪的交互。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-08 18:52:06

必须定义constexpr表达式。您的未定义,因此在这种情况下,int(constexpr_declval<int>())不是constexpr

这意味着maybe_noexcept(int(constexpr_declval<int>()))不是constexprnoexcept也不是。

编译器正确地返回false

您也不能在constexpr中调用UB。

我想不出一种对任意数据进行constexpr引用的方法。我认为对齐存储的constexpr缓冲区被重新解释为对数据类型的引用,但在许多情况下是UB,因此不是-constexpr

一般来说,这是不可能的。假设您有一个类,其状态确定方法调用是否为constexpr

代码语言:javascript
运行
复制
struct bob {
  int alice;
  constexpr bob(int a=0):alice(a) {}
  constexpr int get() const {
    if (alice > 0) throw std::string("nope");
    return alice;
  }
};

现在,bob::get constexpr是不是?如果你有一个非正的constexpr bob,并且.如果不是的话。

您不能说“假设此值为constexpr,并告诉我某个表达式是否为constexpr”。即使可以,它也解决不了这个问题,因为如果表达式是constexpr或非constexpr,则会改变参数的状态!

更有趣的是,bob().get()是稳定的,而bob(1).get()则不是。因此,您的第一次尝试(默认构造类型)甚至给出了错误的答案:您可以测试,然后执行操作,该操作将失败。

对象实际上是方法的参数,如果没有al参数的状态,您就无法确定函数是否为constexpr

判断表达式是否为constexpr的方法是在constexpr上下文中运行它并查看它是否工作。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35276564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档