繁体   English   中英

自引用 c++20 概念

[英]Self referential c++20 concepts

以下无效代码的道德等价物是什么?

// Suppose you want to check, as part of a concept,
// if some operation on a type results in a type that models such concept.
// you cannot constrain the resulting type with the same concept
// in the same way you can't have self referential types
// (that would result in recursive definitions)

template<class T>
concept Int = requires(const T& a, const T& b) {
  { a + b } -> Int; // compiler don't know what to do
};

假设您要检查作为概念的一部分,对类型的某些操作是否会导致模型化此类概念的类型。

那是无限递归。 像任何函数递归一样,您必须有一个终止条件。 为模板 arguments 定义终止条件的常规方法是通过特化。 但是concept不能明确地特化,所以不能有终结条件。

它在逻辑上也是不连贯的,因为你试图通过使用你试图定义的东西来编写一个定义。 没有“道德上的等价物”来定义根据定义没有意义的东西。

您的概念似乎是在说“ T应该是我可以添加到另一个T并产生的东西......”什么? 您是否希望它能够产生一些不相关的U类型,可以将其添加到另一个U以产生...再次,什么? 即使忽略这个问题, U是否应该能够被添加到T 如果是这样,那应该产生什么?

编写概念时,从用例开始,先决定要执行的操作。

可以进行这种递归模板检查,但它使代码难以阅读。 原理是将递归模板检查转发到通过依赖名称查找找到的function,只有当类型不属于已检查类型列表时才会验证其约束...如果类型属于已检查类型列表检查类型,function 被 SFINAE 禁用,另一个不递归引用该概念的 function 由重载决议选择:

实际操作: compiler-explorer-link

#include <type_traits>

namespace trying{

    struct to_do{};

    template <class...Checked, class T>
    std::enable_if_t <(std::is_same_v <T,Checked> || ...), std::true_type> 
    too_complex(T &&, to_do);

    template <class...Checked, class T>
    std::false_type 
    too_complex(T &&,...);
}

template <class U, class T, class...Checked>
concept Integer_= requires(const T& a, const T& b, const U& to_be_readable)
   {
   requires decltype(too_complex <T, Checked...> (a + b, to_be_readable))::value ;
   };

template <class T, class...Checked>
concept Integer = Integer_ <trying::to_do, T, Checked...>;

namespace trying{
    template <class...Checked, class T>
    requires (Integer <T, Checked...>)
    std::enable_if_t <!(std::is_same_v <T,Checked> || ...), std::true_type> 
    too_complex(T &&, to_do);
}

struct x{
    auto
    operator + (x) const -> int;
};
struct y{
    auto
    operator + (y) const -> void*;
};

struct z2;
struct z1{
    auto
    operator + (z1) const -> z2;
};
struct z2{
    auto
    operator + (z2) const -> z1;
};

static_assert (Integer <int>);
static_assert (Integer <x>);
static_assert (!Integer <y>);
static_assert (Integer <z1>);
static_assert (Integer <z2>);

所以是的,这是可能的……但我认为不应该这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM