非类型模板参数和需要

NoS*_*tAl 10 c++ c++-concepts c++20 non-type-template-parameter

我正在学习概念,我想不出一种方法来限制非类型模板参数的值(不是类型)。

编译的代码示例,尽管我希望它没有(由于需求失败):

#include <cassert>

enum Bla{
    Lol, 
    Haha
};

template<Bla b>
requires requires{
    // my guess is that this just checks that this is valid expression, not
    // that it is true
    b>1; 
}
void f(){
    assert(b>1);
}

int main() {
    f<Lol>(); // compiles, not funny ;)
}
Run Code Online (Sandbox Code Playgroud)

注意:这是一个简化的例子(我想要“模板重载”)所以static_assert对我不利,我试图避免,std::enable_if因为语法是可怕的。

cig*_*ien 5

由于只f需要受非类型模板参数的值约束,你可以简单地编写一个requires子句而不是一个临时requires requires约束:

template<Bla b>
requires (b>1) 
void f() {}
Run Code Online (Sandbox Code Playgroud)

这是一个演示

requires requires如果您想对模板参数进行更复杂的检查,您只需要一个表达式。在这种情况下,我建议无论如何使用命名概念而不是临时约束。这使代码更具可读性,并允许您在其他地方重用该概念。


至于assert,它是一个运行时构造,因此它不会以任何方式影响编译,假设 中的表达式在assert语法上是有效的。static_assert如果要在编译时检查模板参数,则需要改用:

static_assert(b>1);
Run Code Online (Sandbox Code Playgroud)


Hol*_*Cat 5

如果您只有布尔条件而没有其他条件,请执行以下操作:

template<Bla b>
requires(b > 1)
void f() {}
Run Code Online (Sandbox Code Playgroud)

替代更长的语法,如果您需要在同一个requires表达式中检查更多内容:

template<Bla b>
requires requires
{
    requires b > 1;
//  ^~~~~~~~
}
void f() {}
Run Code Online (Sandbox Code Playgroud)

  • [为什么要停止](https://wandbox.org/permlink/7fVVXJjQSUWHC6R8) 仅将一个 _requires-expression_ 嵌套在另一个表达式中?;) (2认同)
  • @dfrib 您刚刚发现了一个带有 `__PRETTY_FUNCTION__` 的 GCC 错误。:P (2认同)