【问题标题】:Can concepts be used with CRTP idiom?概念可以与 CRTP 成语一起使用吗?
【发布时间】:2020-06-15 14:52:52
【问题描述】:

鉴于以下奇怪的重复模板模式 (CRTP) 代码示例:

template<typename X>
struct Base {
  X f() const { return X{}; }
};

template<template<typename> typename T>
struct Derived : T<Derived<T>>
{};

const Derived<Base> d0{};
const Derived<Base> d1 = d0.f();

我开始怀疑是否可以使用概念来限制可能的基类集。我的想法,基于this answer 假设使用requires B&lt;T, Derived&lt;T&gt;&gt;,其中B 定义如下:

#include <concepts>

// ...

template<template<typename> typename T, typename X>
concept B = requires (T<X> t)
  {
   { t.f() } -> std::convertible_to<X>;
  };

显然,我不能使用这种形式:

template<template<typename> typename T> requires B<T, Derived<T>>
struct Derived : T<Derived<T>>
{};

因为 require-clause 中的 Derived 尚未定义。这个:

template<template<typename> typename T>
struct Derived requires B<T, Derived<T>> : T<Derived<T>>
{};

还有这个:

template<template<typename> typename T>
struct Derived : T<Derived<T>> requires B<T, Derived<T>>
{};

也不要解决问题。

有没有办法克服这些困难并将概念与 CRTP 结合起来?

(我在 GCC 10.0.1 上进行了测试。)

【问题讨论】:

  • "考虑到奇怪的重复模板模式 (CRTP)" 这是一个奇怪的 CRTP 示例。 CRTP 中的派生类通常知道它们将使用哪些 CRTP 基类。如果这是出于组合原因(您打算以 CRTP 方式从Derived 继承),那么最终的 CRTP 基类需要使用 final 派生类类型,而不是中间类型。
  • 目前还不清楚这有什么意义。如果Derived 是一个不知道 CRTP 基类在做什么的中间类,它应该接受任何东西。如果Derived知道 CRTP 基类在做什么......那么它要么知道它正在使用哪个类(模板),要么知道这个模板的接口是什么。该接口将是定义 CRTP 基类的概念,而不是派生类。
  • @NicolBolas 1. 也许我没有理解你的评论,但我不认为我的例子很奇怪——我什至看过可变参数 CRTP,它很好。 2. 在我的示例中,我不想从Derived 继承。 3.我想明确定义概念为类之间的抽象层。
  • "我想明确地将概念定义为类之间的抽象层。" 但是你没有类。你的Derived 需要一个模板,而不是一个类。并且您的代码正在使用定义的类型开始实例化该模板。您不能基于尚不存在的东西来限制模板。
  • 我想我不明白你想在这里建立什么样的关系。 CRTP 通常用于通过插入可以访问派生类和/或派生类可以访问的成员来将行为注入派生类。您是否试图对正在增强的特定事物施加限制?

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


【解决方案1】:

我已经阅读了一个提议,该提议建议定义对类定义的约束。但它没有合并到标准中。因此,如果您想约束类定义,我知道的唯一解决方法是在完全定义类的上下文中使用静态断言,因此在成员函数体内:

    template <class Base>
struct A: Base 
    {

     A() {
          static_assert(a_concept <A>);
          }
    };

【讨论】:

    猜你喜欢
    • 2022-10-14
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多