实现 Pair with C++20 概念的概念

Ami*_*rsh 4 c++ c++-concepts c++20

要打印任何类型,std::pair我们可以实现以下方法:

template<typename First, typename Second>
void printPair(const std::pair<First, Second>& p) {
    std::cout << p.first << ", " << p.second << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但是假设我们要实现一个方法,可以打印任何类型的对,不一定是std::pair,基于以下要求:

  • 它有 afirstsecondpublic 字段
  • 它有 afirst_typesecond_typepublic 内部类型
  • first== 的类型first_type
  • second== 的类型second_type

有一个concept,我们称之为Pair,可以允许编写一个方法,如:

void printPair(const Pair auto& p) {
    std::cout << p.first << ", " << p.second << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

这样的一个怎么concept定义?

T.C*_*.C. 8

这里有一些有趣的微妙之处。

template<class P>
concept Pair = requires(P p) {
    typename P::first_type;
    typename P::second_type;
    p.first;
    p.second;
    requires std::same_as<decltype(p.first), typename P::first_type>;
    requires std::same_as<decltype(p.second), typename P::second_type>;
};
Run Code Online (Sandbox Code Playgroud)

前四行有些多余,但可以帮助生成更好的错误消息。其余的行应该是不言自明的。请注意,decltype对普通类成员访问的使用会产生数据成员的声明类型。

最后两行也可以写成

    { p.first } -> std::same_as<typename P::first_type&>;
    { p.second } -> std::same_as<typename P::second_type&>;
Run Code Online (Sandbox Code Playgroud)

在这里,复合要求类型约束应用于decltype((p.first))。该表达式是左值,因此生成的类型是左值引用类型。请注意,此版本将同时接受first_type first;first_type& first;