如何在 C++ 概念中实现属性

How to implement properties in C++ concepts

C++ 概念在 C++ 中是一个相对较新的概念。 但是我们几乎没有关于它是如何工作的解释。

struct contain {
public:
  using Tin = int;
  using Tout = int;
  Tout sqr(Tin x)
  {
    return x * x;
  }
  contain(int _x) : x(_x)
  {
  }
  int get_x() const
  {
    return x;
  }
private:
  int x;
};


int cube(contain u)
{
  int x = u.get_x();
  return x * x * x;
}

也就是我们要有一个概念,tests包含TinTout和一个成员函数 Tout sqr(Tin)。是否也可以测试是否存在非成员函数 cube(contain)?

That is we want to have a concept that tests that contain contains Tin, Tout and a member function Tout sqr(Tin). Would it also be possible to test if there is a non-member function cube(contain)?

这有点取决于你的意思。您当然可以为行为“足够像”的东西写一个概念 contain:

#include <concepts>

template<class C>
concept ContainLike = requires(C c, typename C::Tin in) // typename only needed for Clang, until it implements P0634
{
    { c.sqr(in) } -> std::same_as<typename C::Tout>;
    cube(c);
};

See it live

该概念检查类型 C,当给定两个类型为 CC::Tin 的假设对象时,显式约束列表成立:

  1. c.sqr(in) 格式正确并且 returns C::Tout.
  2. cube(c) 格式正确(在我们的例子中可以通过 ADL 找到)。此处不限制表达式的类型。

请注意,C::ToutC::Tin 的测试在这里是隐含的。如果 C 不包含这些类型,这将是替换失败,这将使概念不被满足(以 SFINAE 友好的方式)。

另一件值得一提的事情是,这不会检查 C 是否包含参数为 Tinsqr 方法。相反,它检查 Tin 是否可以作为参数传递(这可能需要转换为实际参数类型)。这是概念的更自然的用法:duck typing。