c++ - 在类声明中使用概念

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

结构 Vec 具有成为 std::default_initializable 的所有要求。但是声明还没有结束,所以编译失败。

template <std::default_initializable A>
struct It {};

struct Vec { 
    using Iterator = It<Vec>;
};

是否有某种解决方法来保持 It 要求?

最佳答案

一般来说,您的问题的答案是否定的。如果你想创建一个成员类型别名,它必须在相关时间是已知的。如果您尝试实例化的模板要求给定的类型是完整的(default-initializable 就是这样),那么它必须是完整的。

然而,在您的特定情况下,并不是真的有必要制作 Iterator成员。如果你想要范围的迭代器类型,正确的方法是使用 ranges::iterator_t .和 that meta-function将返回 ranges::begin() 的类型返回。

你的 begin可以指定成员函数返回auto , 这样函数的定义就是提供 It<Vec> 的, as follows :

template <std::default_initializable A>
struct It {};

struct Vec
{ 
    auto begin() {return It<Vec>(...);}
};

话虽如此,即使您想在它所服务的容器/范围之外定义迭代器类型,它仍然绑定(bind)到该容器/范围类型。除非It是某种 View 或范围转换(如果是,它可能不应该默认构建它修改的范围),It<UserType>不应该工作。因此,约束 It模板毫无意义;你知道 Vec是默认可构造的,因为您将该类写在迭代器的正下方。如果你想要一个完整性检查,你可以使用 static_assert , 但您不需要约束模板本身。

关于c++ - 在类声明中使用概念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66987676/

相关文章:

c++ - 从使用概念定义的函数返回新对象

c++ - 向量化嵌套循环 - SIMD

c++ - 类包装器的模板特化

scala - 使用 Scala 特征对 C++ 概念进行建模

c++ - 如何测试标准库中是否定义了 std::remove_cvref?

c++ - 为什么我们需要 C++ 中的 spaceship <=> 运算符?

c++ - 以下小于(<)运算符对于什么类型 T 是合法的?

c++ - 为什么基于指针交换两个值在函数范围之外不起作用?

c++ - GLSL 照明作为平面 - 法线问题?

c++ - 如何以多态方式创建对象的动态数组?