在 class 声明中使用概念
Using concept inside class declaration
结构 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 将 return ranges::begin()
return 的类型。
您的 begin
成员函数可以指定为 return auto
,这样函数的定义就是提供 It<Vec>
、as follows :
template <std::default_initializable A>
struct It {};
struct Vec
{
auto begin() {return It<Vec>(...);}
};
话虽如此,即使您想在它所服务的 container/range 之外定义迭代器类型,它仍然 绑定 到 container/range 类型。除非 It
是某种视图或范围转换(如果是,它可能不应该默认构建它修改的范围),It<UserType>
不应该工作。因此,限制 It
模板是没有意义的;你 知道 Vec
是默认可构造的,因为你在迭代器下面写了 class。如果你想要完整性检查,你可以使用 static_assert
,但你不需要约束模板本身。
结构 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 将 return ranges::begin()
return 的类型。
您的 begin
成员函数可以指定为 return auto
,这样函数的定义就是提供 It<Vec>
、as follows :
template <std::default_initializable A>
struct It {};
struct Vec
{
auto begin() {return It<Vec>(...);}
};
话虽如此,即使您想在它所服务的 container/range 之外定义迭代器类型,它仍然 绑定 到 container/range 类型。除非 It
是某种视图或范围转换(如果是,它可能不应该默认构建它修改的范围),It<UserType>
不应该工作。因此,限制 It
模板是没有意义的;你 知道 Vec
是默认可构造的,因为你在迭代器下面写了 class。如果你想要完整性检查,你可以使用 static_assert
,但你不需要约束模板本身。