gpt4 book ai didi

c++ - constexpr decltype

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:23:40 26 4
gpt4 key购买 nike

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

template <class T>
constexpr int maybe_noexcept(T && t) { return 0; }
...
constexpr bool b = noexcept(maybe_noexcept(int{}));

这行得通并且 b 正如您所期望的那样为真,因为对 int 进行零初始化是一个常量表达式。它也应该正确地产生零(如果我将 int 更改为其他一些合适的类型)。

接下来,我想检查 constexpr 移动是否可构造。所以我这样做了:

constexpr bool b = noexcept(maybe_noexcept(int(int{})));

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

constexpr bool b = noexcept(maybe_noexcept(int(declval<int>())));

这导致 b 在 gcc 5.3.0 中为 false(不能将 clang 用于其中任何一个,因为 clang 不能正确地生成常量表达式 noexcept)。没问题,我说,一定是因为 declval(很有趣)没有标记为 constexpr。所以我写了我自己的幼稚版本:

template <class T>
constexpr T&& constexpr_declval() noexcept;

是的,与标准库的做法相比,这是幼稚的,因为它会因 void 和其他可能的原因而窒息,但目前还好。所以我再试一次:

constexpr bool b = noexcept(maybe_noexcept(int(constexpr_declval<int>())));

这仍然不起作用,b 始终为 false。为什么这不被视为常量表达式?这是编译器错误,还是我不了解 constexpr 的基础知识?似乎 constexpr 和未评估的上下文之间存在一些奇怪的交互。

最佳答案

constexpr必须定义表达式。你的没有定义,所以在那种情况下int(constexpr_declval<int>())不是 constexpr .

这意味着 maybe_noexcept(int(constexpr_declval<int>()))不是 constexpr ,所以不是noexcept .

并且编译器正确返回 false .

您也不能在 constexpr 中调用 UB .

我想不出制作 constexpr 的方法引用任意数据。我在想 constexpr对齐存储的缓冲区重新解释为对数据类型的引用,但在许多上下文中是 UB,因此不是- constexpr .

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

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用非正 alice 构建, 并且...如果不是的话就不是。

你不能说“假装这个值是 constexpr 并告诉我某个表达式是否是 constexpr”。即使可以,它也不能解决一般问题,因为 constexpr状态如果表达式为 constexpr,则参数可以更改还是不是!

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

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

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

关于c++ - constexpr decltype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35276564/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com