gpt4 book ai didi

c++ - 如何解决 requires 子句不兼容

转载 作者:行者123 更新时间:2023-12-05 09:07:14 28 4
gpt4 key购买 nike

我正在尝试实现递归版本 std::iter_value_t 与 C++20 概念使得基类型 T嵌套容器,如 std::vector<std::vector<...std::vector<T>...>>可以检索。实验实现如下。

template<typename T>
concept is_iterable = requires(T x)
{
*std::begin(x);
std::end(x);
};

template<typename T> requires (!is_iterable<T>)
struct recursive_iter_value_t_detail
{
typedef typename T type;
};

template<typename T> requires (is_iterable<T>)
struct recursive_iter_value_t_detail
{
typedef typename std::iter_value_t<typename recursive_iter_value_t_detail<T>::type> type;
};

template<typename T>
using recursive_iter_value_t = typename recursive_iter_value_t_detail<T>::type;

尝试编译这段代码后,唯一的错误信息是'recursive_iter_value_t_detail': requires clause is incompatible with the declaration弹出,我不确定是什么 requires clause is incompatible with the declaration意义。问题是template struct不能这样重载吗?请帮我解决这个问题。

recursive_iter_value_t<std::vector<std::vector<int>>> 的预期输出是int .

最佳答案

很多东西。

首先,C++20 已经有了可迭代性的概念:它叫做 std::ranges::range .

其次,自 C++11 以来,没有理由使用 typedef .一直喜欢using . typename的使用也无效。所以using type = T;而不是 typedef typename T type;原因是using更强大(除了普通别名之外,您还可以拥有别名模板)并且它是一种更明智的语法(您要引入的名称位于 = 的左侧,而不是......基本上任何地方)。

三、正确编写约束类模板偏特化的方法是主无约束:

template <typename T>
struct recursive_iter_value_t_detail {
using type = T;
};

和其他 (a) 主要的限制更多,并且 (b) 实际上必须是特化的(请参阅语法中额外的 <T>):

template <typename T> requires std::ranges::range<T>
struct recursive_iter_value_t_detail<T> {
// ...
};

这也可以拼写:

template <std::ranges::range T>
struct recursive_iter_value_t_detail<T> {
// ...
};

最后,你的递归步骤是倒退的。如果它是一个范围,则需要 解包,然后范围然后 递归。您目前首先递归——但在同一类型上,所以这是无限递归。所以应该是:

using type = recursive_iter_value_t_detail<std::iter_value_t<T>>::type;

你可以把它写得更短:

template <std::ranges::range T>
struct recursive_iter_value_t_detail<T>
: recursive_iter_value_t_detail<std::iter_value_t<T>>
{ };

放在一起[demo] :

template<typename T>
struct recursive_iter_value_t_detail
{
using type = T;
};

template <std::ranges::range T>
struct recursive_iter_value_t_detail<T>
: recursive_iter_value_t_detail<std::iter_value_t<T>>
{ };

template<typename T>
using recursive_iter_value_t = typename recursive_iter_value_t_detail<T>::type;

关于c++ - 如何解决 requires 子句不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65210374/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com