【问题标题】:How to implement properties in C++ concepts如何在 C++ 概念中实现属性
【发布时间】:2021-04-04 09:31:56
【问题描述】:

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;
}

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

【问题讨论】:

  • 你确定我们说的是同一件事吗?概念旨在与模板参数一起使用,like this。您是否要求一个需要与您的contains 具有相同接口 的东西的概念?
  • 概念不是那个新想法。 C++ 很久以来就有named requirements,不同的是概念是语言的一部分。它不太清楚你在问什么。您有一些模板想要检查是否有一些 T 嘎嘎,就像您的 contains 嘎嘎一样?
  • 是的。你试过了吗?采取方法语法并以明显的方式更改它?
  • 我可以为依赖类型 Tin, Tout 写一个概念。但我可以为 sqr 和 cube 做到这一点。总的来说,我发现在通常的网站上 C++ 概念的例子太少了,很可能是因为它们是新的。

标签: c++ c++20 c++-concepts


【解决方案1】:

也就是说,我们想要一个包含TinTout 和成员函数Tout sqr(Tin) 的测试概念。是否也可以测试是否有非成员函数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) 格式正确并返回 C::Tout
  2. cube(c) 格式正确(在我们的例子中可以通过 ADL 找到)。表达式的类型在这里不受限制。

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

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

【讨论】:

    猜你喜欢
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    相关资源
    最近更新 更多