gpt4 book ai didi

c++ - consteval 会允许在函数参数上使用 static_assert 吗?

转载 作者:可可西里 更新时间:2023-11-01 17:43:49 24 4
gpt4 key购买 nike

目前您不能使用 static_assert 来验证 constexpr 函数的参数,即使对它的所有调用确实都是 constexpr。这是有道理的,因为编译器仍然必须创建此函数的非 constexpr 实例,以防其他模块尝试调用它。遗憾的是,即使函数是 static 或在匿名命名空间中也是如此。

但是,C++20 将引入一个新关键字 consteval,它类似于 constexpr,但它不允许以非 constexpr 方式调用函数。在这种情况下,编译器可以确定函数参数在编译时总是已知的。因此,理论上应该可以使用 static_assert 来验证它们。

问题是:标准允许吗?


例子:

#include <iostream>

consteval char operator""_bchar(const char text[], const size_t length)
{
static_assert(length == 8, "Binary char has to have 8 digits!"); // <-- This is currently not possible.
uint8_t byte = 0;
for (size_t i = 0; i != length; ++i)
{
byte <<= 1;
byte |= text[i] == '1' ? 0b00000001 : 0b00000000;
}
return byte;
}

int main()
{
std::cout << "01000001"_bchar << std::endl;
return 0;
}

我问是因为我要写一些用户定义的文字(比示例更复杂)。我可以选择使用编译器扩展来处理验证,或者等待编译器更新并编写完全符合标准的代码。

最佳答案

Will consteval allow to use static_assert on function arguments?

没有。函数参数从来没有,也将继续不能用作常量表达式。

常量求值和可用作常量表达式是有区别的。 consteval 确保我们处于常量计算上下文中,但它不会导致所有内容都变成常量表达式。

为了让函数参数可以用作常量表达式,您需要将所有内容隐式地设为模板:

template <int> struct X { };

consteval auto foo(int i) {
static_assert(i > 10); // in order to allow this...
return X<i>{}; // ... you'd have to allow this too
}

现在 foo(20)foo(30) 返回不同的类型。那是一个模板。


可以在 Andrew Sutton 的 Translation and evaluation: A mental model for compile-time metaprogramming 中找到了解为什么这是一个基本和固有限制的重要背景阅读。 :

Having a mental model of compile-time evaluation that physically separates it from the process of translation has been extremely helpful for me. In particular, it has helped me understand what is not possible (e.g., instantiating a template during evaluation). This helps prune the design space for otherwise large and complex language features. Hopefully, others will find this note helpful as well.


不过,特别是使用 static_assert 时,您可以添加一个解决方法来导致编译失败。这只是添加了在不断评估期间无法使用的任何东西。喜欢:

#define CONSTEVAL_STATIC_ASSERT(c, msg) do { if (!(c)) throw msg; } while(false)

如:

consteval char operator""_bchar(const char text[], const size_t length)
{
CONSTEVAL_STATIC_ASSERT(length == 8, "Binary char has to have 8 digits!");
// ...
}

关于c++ - consteval 会允许在函数参数上使用 static_assert 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57226797/

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