【问题标题】:Using concept inside class declaration在类声明中使用概念
【发布时间】:2021-04-07 13:58:14
【问题描述】:
结构Vec 具有std::default_initializable 的所有要求。但是声明没有完成,所以编译失败。
template <std::default_initializable A>
struct It {};
struct Vec {
using Iterator = It<Vec>;
};
是否有某种解决方法来保持It 要求?
【问题讨论】:
标签:
c++
c++20
c++-concepts
【解决方案1】:
一般来说,您的问题的答案是否定的。如果您想创建成员类型别名,则必须在相关时间知道它。如果你试图实例化的模板要求它给出的类型是完整的(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>(...);}
};
话虽如此,即使您想在它所服务的容器/范围之外定义迭代器类型,它仍然绑定到该容器/范围类型。除非It 是某种视图或范围转换(如果是,它可能不应该默认构造它修改的范围),It<UserType> 不应该工作。因此,约束It 模板是没有意义的;您知道 Vec 是默认可构造的,因为您在迭代器下方编写了该类。如果您想要进行完整性检查,可以使用static_assert,但您不需要约束模板本身。