专业的编程技术博客社区

网站首页 > 博客文章 正文

C++(八):concept和requires的直观认识

baijin 2024-10-12 02:08:55 博客文章 12 ℃ 0 评论

concept输入模板参数,输出一个bool类型字面量。

例如:

auto is_int = std::integral<int>;

std::cout << "The type of std::integral<int> : " << type_to_string<decltype(std::integral<int>)>() << std::endl;
std::cout << "The value type of std::integral<int> : " << type_to_string<decltype((std::integral<int>))>() 
          << std::endl;

输出:

The type of std::integral<int> : bool
The value type of std::integral<int> : bool

concept最后输出的结果的值类型是个纯右值,也就是个字面量。我们可以将concept的结果当成字面量使用,也可以用字面量替代concept的结果,在requires中使用。

concept结果当字面量用

例如,输入输出:

auto is_int = std::integral<int>;

std::cout << std::boolalpha;
std::cout << "is_int : " << is_int << std::endl;

输出:

is_int : true

字面量当concept用

template<typename T>
requires true
void g(T a) {
    std::cout << a << std::endl;
}

int main() {
    g(10);
}

输出:

10

requires

requires分两种,一种是在template下面的,用来判断concept是否满足的,例如下面的例子:

template<typename T>
requires std::integral<T>
void g(T a) {
    std::cout << a << std::endl;
}

一种是带表达式的,和一个函数形式类似,例如:

template<typename T>
concept can_exec = requires(T a) {
    a%10;
};

int main() {
    std::cout << std::boolalpha;
    std::cout << can_exec<int> << std::endl;
    std::cout << can_exec<float> << std::endl;
}

输出:

true
false

其中:

requires(T a) {
    a%10;
};

并不实际求值,只是判断{}内的表达式能否运行。再看个例子:

template<typename T>
concept can_exec1 = requires(T a) {
    false;
};

int main() {
    std::cout << std::boolalpha;
    std::cout << can_exec1<int> << std::endl;
    std::cout << can_exec1<float> << std::endl;
}

输出:

true
true

所以,对于requires(...){}来说,只要{}中的表达式能运行,就会返回真。

int main() {
    auto can_exec2 = requires(int a, int b){
        a+b;
    };
    std::cout << std::boolalpha;
    std::cout << can_exec2 << std::endl;
}

输出:

true

requires(...){}主要用来判断表达式能否运行,返回一个bool字面量

当然,也可以直接在template中运用

template<typename T>
requires 
    requires{
        false;
    }
void g1(T a) {
    std::cout << a << std::endl;
}
g1(10)

输出:

10

requires表达式中还可以再嵌套第一种requires

如果直接使用,会报错:

// int main() {
//     auto can_exec2 = requires std::integral<int>;
//     std::cout << std::boolalpha;
//     std::cout << can_exec2 << std::endl;
// }
// error: expected '{' before 'std'
int main() {
    auto can_exec2 =requires{
        requires std::integral<int>;
    };
    std::cout << std::boolalpha;
    std::cout << can_exec2 << std::endl;
}

输出:

true

还可以这样用

int main() {

  float a = 2.2;
  int b = 3;

  auto f = [&]<typename T>(T a) {
    auto can_exec2 = requires(T value) { requires std::integral<T>; };
    return can_exec2;
  };

  std::cout << std::boolalpha;
  std::cout << f(a) << std::endl;
  std::cout << f(b) << std::endl;
}

这样用:

template <typename T>
requires requires { requires std::integral<int>; }
void g1(T a) { std::cout << a << std::endl; }

用来约束lambda表达式

auto f = [&]<typename T>requires std::integral<T>(T a) {
  };

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表